Implying different vehicle constraint in Google OR tool for CVRPTW considering Resource Allocation - Python

Im currently using the Google OR tool for CVRPTW considering Resource Allocation. However, I would like to add certain more parameters into it, such as:

Adding different vehicle speeds
Adding different package capacity for each of the vehicle used
Having the vehicles deliver packages rather than picking them up.

And if possible: considering multiple depot
I read through the documentation, and I figured out that I need to use AddDimensionWithVehicleTransits() to add a new constraint, but I don't know how to implement this in the code.
Any help will be nice.
Data model:
import math
from ortools.constraint_solver import pywrapcp
from ortools.constraint_solver import routing_enums_pb2

def distance(x1, y1, x2, y2):
    # Manhattan distance
    dist = abs(x1 - x2) + abs(y1 - y2)

    return dist

# Distance callback

class CreateDistanceCallback(object):
  """Create callback to calculate distances and travel times between points."""

  def __init__(self, locations):
    """Initialize distance array."""

    num_locations = len(locations)
    self.matrix = {}

    for from_node in xrange(num_locations):
      self.matrix[from_node] = {}
      for to_node in xrange(num_locations):
        x1 = locations[from_node][0]
        y1 = locations[from_node][1]
        x2 = locations[to_node][0]
        y2 = locations[to_node][1]
        self.matrix[from_node][to_node] = distance(x1, y1, x2, y2)

  def Distance(self, from_node, to_node):
    return int(self.matrix[from_node][to_node])

# Demand callback
class CreateDemandCallback(object):
  """Create callback to get demands at each node."""

  def __init__(self, demands):
    self.matrix = demands

  def Demand(self, from_node, to_node):
    return self.matrix[from_node]

# Service time (proportional to demand) + transition time callback.
class CreateServiceTimeCallback(object):
  """Create callback to get time windows at each node."""

  def __init__(self, demands, time_per_demand_unit):
    self.matrix = demands
    self.time_per_demand_unit = time_per_demand_unit

  def ServiceTime(self, from_node, to_node):
    return self.matrix[from_node] * self.time_per_demand_unit

# Create total_time callback (equals service time plus travel time).
class CreateTotalTimeCallback(object):
  def __init__(self, service_time_callback, dist_callback, speed):
    self.service_time_callback = service_time_callback
    self.dist_callback = dist_callback
    self.speed = speed

  def TotalTime(self, from_node, to_node):
    return self.service_time_callback(from_node, to_node) + self.dist_callback(from_node, to_node) / self.speed

def DisplayPlan(routing, assignment):

  # Display dropped orders.
  dropped = ''

  for order in range(1, routing.nodes()):
    if assignment.Value(routing.NextVar(order)) == order:
      if (dropped.empty()):
        dropped += " %d", order
      else: dropped += ", %d", order

  if not dropped.empty():
    plan_output += "Dropped orders:" + dropped + "\n"

  return plan_output

def main():
  # Create the data.
  data = create_data_array()
  locations = data[0]
  demands = data[1]
  start_times = data[2]
  num_locations = len(locations)
  depot = 0
  num_vehicles = 5
  search_time_limit = 400000

  # Create routing model.
  if num_locations > 0:

    # The number of nodes of the VRP is num_locations.
    # Nodes are indexed from 0 to tsp_size - 1. By default the start of
    # a route is node 0.
    routing = pywrapcp.RoutingModel(num_locations, num_vehicles, depot)
    search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

    # Callback to the distance function.

    dist_between_locations = CreateDistanceCallback(locations)
    dist_callback = dist_between_locations.Distance

    routing.SetArcCostEvaluatorOfAllVehicles(dist_callback)
    demands_at_locations = CreateDemandCallback(demands)
    demands_callback = demands_at_locations.Demand

    # Add capacity dimension constraints.
    vehicle_capacity = 100;
    null_capacity_slack = 0;
    fix_start_cumul_to_zero = True
    capacity = "Capacity"
    routing.AddDimension(demands_callback, null_capacity_slack, vehicle_capacity,
                         fix_start_cumul_to_zero, capacity)

    # Adding time dimension constraints.
    time_per_demand_unit = 300
    horizon = 24 * 3600
    time = "Time"
    tw_duration = 5 * 3600
    speed = 10

    service_times = CreateServiceTimeCallback(demands, time_per_demand_unit)
    service_time_callback = service_times.ServiceTime
    total_times = CreateTotalTimeCallback(service_time_callback, dist_callback, speed)
    total_time_callback = total_times.TotalTime

    # Note: In this case fix_start_cumul_to_zero is set to False,
    # because some vehicles start their routes after time 0, due to resource constraints.

    fix_start_cumul_to_zero = False
    # Add a dimension for time and a limit on the total time_horizon
    routing.AddDimension(total_time_callback,  # total time function callback
                         horizon,
                         horizon,
                         fix_start_cumul_to_zero,
                         time)

    time_dimension = routing.GetDimensionOrDie("Time")

    for order in range(1, num_locations):
      start = start_times[order]
      time_dimension.CumulVar(routing.NodeToIndex(order)).SetRange(start, start + tw_duration)
    # Add resource constraints at the depot (start and end location of routes).

    vehicle_load_time = 180
    vehicle_unload_time = 180
    solver = routing.solver()
    intervals = []
    for i in range(num_vehicles):
      # Add time windows at start of routes
      intervals.append(solver.FixedDurationIntervalVar(routing.CumulVar(routing.Start(i), time),
                                                     vehicle_load_time,
                                                     "depot_interval"))
      # Add time windows at end of routes.
      intervals.append(solver.FixedDurationIntervalVar(routing.CumulVar(routing.End(i), time),
                                                     vehicle_unload_time,
                                                     "depot_interval"))
    # Constrain the number of maximum simultaneous intervals at depot.
    depot_capacity = 2;
    depot_usage = [1 for i in range(num_vehicles * 2)]
    solver.AddConstraint(
      solver.Cumulative(intervals, depot_usage, depot_capacity, "depot"))
    # Instantiate route start and end times to produce feasible times.
    for i in range(num_vehicles):
      routing.AddVariableMinimizedByFinalizer(routing.CumulVar(routing.End(i), time))
      routing.AddVariableMinimizedByFinalizer(routing.CumulVar(routing.Start(i), time))

    # Solve, displays a solution if any.
    assignment = routing.SolveWithParameters(search_parameters)
    if assignment:

      # Solution distance.
      print "Total distance of all routes: " + str(assignment.ObjectiveValue()) + "\n"
      # Display solution.

      capacity_dimension = routing.GetDimensionOrDie(capacity);
      time_dimension = routing.GetDimensionOrDie(time);

      for vehicle_nbr in range(num_vehicles):
        index = routing.Start(int(vehicle_nbr))
        plan_output = 'Route {0}:'.format(vehicle_nbr)

        while not routing.IsEnd(index):
          node_index = routing.IndexToNode(index)
          load_var = capacity_dimension.CumulVar(index)
          time_var = time_dimension.CumulVar(index)
          plan_output += \
                    " {node_index} Load({load}) Time({tmin}, {tmax}) -> ".format(
                        node_index=node_index,
                        load=assignment.Value(load_var),
                        tmin=str(assignment.Min(time_var)),
                        tmax=str(assignment.Max(time_var)))
          index = assignment.Value(routing.NextVar(index))

        node_index = routing.IndexToNode(index)  # Convert index to node
        load_var = capacity_dimension.CumulVar(index)
        time_var = time_dimension.CumulVar(index)
        plan_output += \
                  " {node_index} Load({load}) Time({tmin}, {tmax})".format(
                      node_index=node_index,
                      load=assignment.Value(load_var),
                      tmin=str(assignment.Min(time_var)),
                      tmax=str(assignment.Max(time_var)))
        print plan_output
        print "\n"
    else:
      print 'No solution found.'
  else:
    print 'Specify an instance greater than 0.'
def create_data_array():

  locations = [[82, 76],
               [96, 44],
               [50, 5],
               [49, 8],
               [13, 7],
               [29, 89],
               [58, 30],
               [84, 39],
               [14, 24],
               [12, 39],
               [3, 82],
               [5, 10],
               [98, 52],
               [84, 25],
               [61, 59],
               [1, 65],
               [88, 51],
               [91, 2],
               [19, 32],
               [93, 3],
               [50, 93],
               [98, 14],
               [5, 42],
               [42, 9],
               [61, 62],
               [9, 97],
               [80, 55],
               [57, 69],
               [23, 15],
               [20, 70],
               [85, 60],
               [98, 5]]

  demands =  [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21, 16, 3, 22, 18,
             19, 1, 24, 8, 12, 4, 8, 24, 24, 2, 20, 15, 2, 14, 9]

  start_times =  [28842, 50891, 10351, 49370, 22553, 53131, 8908,
                  56509, 54032, 10883, 60235, 46644, 35674, 30304,
                  39950, 38297, 36273, 52108, 2333, 48986, 44552,
                  31869, 38027, 5532, 57458, 51521, 11039, 31063,
                  38781, 49169, 32833, 7392]

  data = [locations, demands, start_times]
  return data

if __name__ == '__main__':
  main()`

Hey @Mizux, can you please help me? Im not reaching anywhere :/ Im trying to define each vehicle speed and capacity by using the current distance and dividing it by the respective speed for the vehicle. And define the Horizon for each of the vehicle to use and then use the function AddDimensionWithVehicleTransits() in the time dimension constraint. But Im not getting anywhere with it.

having different vehicle speed means you need one transit function per vehicle then use the AddDimension() which take an array of transit function.
Please take a look at https://github.com/google/or-tools/issues/1032  (based on master branch API)

take a look at https://github.com/google/or-tools/blob/master/ortools/constraint_solver/samples/vrp_capacity.py (based on master branch API)

then each node can have a negative capacity, in this case you must set fix_start_cumul_to_zero to false so vehicle does not start with a "load" of zero.

Dear @Mizux, Thanks a lot for the input. For the first one, I made a def for each of the vehicle transit, after which I added the values for each of the function as an array in the main function Adddimension(), but still not able to get the result. I have added the attempted code below. Can you please guide me? :/
In addition, I want to try changing the horizon value for each of the vehicle. But that should work as the same principle as the vehicle speed right?
Thanks a lot so far!
import math
from ortools.constraint_solver import pywrapcp
from ortools.constraint_solver import routing_enums_pb2

def distance(x1, y1, x2, y2):
    # Manhattan distance
    dist = abs(x1 - x2) + abs(y1 - y2)

    return dist

def vehicletransit0(cust1,cust2):
  return 10

def vehicletransit1(cust1,cust2):
  return 10

def vehicletransit2(cust1,cust2):
  return 15

def vehicletransit3(cust1,cust2):
  return 15

def vehicletransit4(cust1,cust2):
  return 15

# Distance callback

class CreateDistanceCallback(object):
  """Create callback to calculate distances and travel times between points."""

  def __init__(self, locations):
    """Initialize distance array."""

    num_locations = len(locations)
    self.matrix = {}

    for from_node in xrange(num_locations):
      self.matrix[from_node] = {}
      for to_node in xrange(num_locations):
        x1 = locations[from_node][0]
        y1 = locations[from_node][1]
        x2 = locations[to_node][0]
        y2 = locations[to_node][1]
        self.matrix[from_node][to_node] = distance(x1, y1, x2, y2)

  def Distance(self, from_node, to_node):
    return int(self.matrix[from_node][to_node])

# Demand callback
class CreateDemandCallback(object):
  """Create callback to get demands at each node."""

  def __init__(self, demands):
    self.matrix = demands

  def Demand(self, from_node, to_node):
    return self.matrix[from_node]

# Service time (proportional to demand) + transition time callback.
class CreateServiceTimeCallback(object):
  """Create callback to get time windows at each node."""

  def __init__(self, demands, time_per_demand_unit):
    self.matrix = demands
    self.time_per_demand_unit = time_per_demand_unit

  def ServiceTime(self, from_node, to_node):
    return self.matrix[from_node] * self.time_per_demand_unit

# Create total_time callback (equals service time plus travel time).
class CreateTotalTimeCallback(object):
  def __init__(self, service_time_callback, dist_callback, speed):
    self.service_time_callback = service_time_callback
    self.dist_callback = dist_callback
    self.speed = speed

  def TotalTime(self, from_node, to_node):
    return self.service_time_callback(from_node, to_node) + self.dist_callback(from_node, to_node) / self.speed

def DisplayPlan(routing, assignment):

  # Display dropped orders.
  dropped = ''

  for order in range(1, routing.nodes()):
    if assignment.Value(routing.NextVar(order)) == order:
      if (dropped.empty()):
        dropped += " %d", order
      else: dropped += ", %d", order

  if not dropped.empty():
    plan_output += "Dropped orders:" + dropped + "\n"

  return plan_output

def main():
  # Create the data.
  data = create_data_array()
  locations = data[0]
  demands = data[1]
  start_times = data[2]
  num_locations = len(locations)
  depot = 0
  num_vehicles = 5
  search_time_limit = 400000
  vehicletransit = []
  vehicles = [0,1,2,3,4]

  # Create routing model.
  if num_locations > 0:

    # The number of nodes of the VRP is num_locations.
    # Nodes are indexed from 0 to tsp_size - 1. By default the start of
    # a route is node 0.
    routing = pywrapcp.RoutingModel(num_locations, num_vehicles, depot)
    search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

    # Callback to the distance function.

    dist_between_locations = CreateDistanceCallback(locations)
    dist_callback = dist_between_locations.Distance

    routing.SetArcCostEvaluatorOfAllVehicles(dist_callback)
    demands_at_locations = CreateDemandCallback(demands)
    demands_callback = demands_at_locations.Demand

    # Add capacity dimension constraints.
    vehicle_capacity = 100;
    null_capacity_slack = 0;
    fix_start_cumul_to_zero = True
    capacity = "Capacity"
    routing.AddDimension(demands_callback, null_capacity_slack, vehicle_capacity,
                         fix_start_cumul_to_zero, capacity)

    # Adding time dimension constraints.
    time_per_demand_unit = 300
    horizon = 24 * 3600
    time = "Time"
    tw_duration = 5 * 3600
    speed = 10

    for i in range(num_vehicles):
      vehicletransit.append(eval('vehicletransit'+str(vehicles[i])))

    service_times = CreateServiceTimeCallback(demands, time_per_demand_unit)
    service_time_callback = service_times.ServiceTime
    total_times = CreateTotalTimeCallback(service_time_callback, dist_callback, vehicletransit)
    total_time_callback = total_times.TotalTime

    # Note: In this case fix_start_cumul_to_zero is set to False,
    # because some vehicles start their routes after time 0, due to resource constraints.

    fix_start_cumul_to_zero = False
    # Add a dimension for time and a limit on the total time_horizon
    routing.AddDimensionwith(vehicletransit,  # total time function callback
                         horizon,
                         horizon,
                         fix_start_cumul_to_zero,
                         time)

    time_dimension = routing.GetDimensionOrDie("Time")

    for order in range(1, num_locations):
      start = start_times[order]
      time_dimension.CumulVar(routing.NodeToIndex(order)).SetRange(start, start + tw_duration)
    # Add resource constraints at the depot (start and end location of routes).

    vehicle_load_time = 180
    vehicle_unload_time = 180
    solver = routing.solver()
    intervals = []
    for i in range(num_vehicles):
      # Add time windows at start of routes
      intervals.append(solver.FixedDurationIntervalVar(routing.CumulVar(routing.Start(i), time),
                                                     vehicle_load_time,
                                                     "depot_interval"))
      # Add time windows at end of routes.
      intervals.append(solver.FixedDurationIntervalVar(routing.CumulVar(routing.End(i), time),
                                                     vehicle_unload_time,
                                                     "depot_interval"))
    # Constrain the number of maximum simultaneous intervals at depot.
    depot_capacity = 2;
    depot_usage = [1 for i in range(num_vehicles * 2)]
    solver.AddConstraint(
      solver.Cumulative(intervals, depot_usage, depot_capacity, "depot"))
    # Instantiate route start and end times to produce feasible times.
    for i in range(num_vehicles):
      routing.AddVariableMinimizedByFinalizer(routing.CumulVar(routing.End(i), time))
      routing.AddVariableMinimizedByFinalizer(routing.CumulVar(routing.Start(i), time))

    # Solve, displays a solution if any.
    assignment = routing.SolveWithParameters(search_parameters)
    if assignment:

      # Solution distance.
      print "Total distance of all routes: " + str(assignment.ObjectiveValue()) + "\n"
      # Display solution.

      capacity_dimension = routing.GetDimensionOrDie(capacity);
      time_dimension = routing.GetDimensionOrDie(time);

      for vehicle_nbr in range(num_vehicles):
        index = routing.Start(int(vehicle_nbr))
        plan_output = 'Route {0}:'.format(vehicle_nbr)

        while not routing.IsEnd(index):
          node_index = routing.IndexToNode(index)
          load_var = capacity_dimension.CumulVar(index)
          time_var = time_dimension.CumulVar(index)
          plan_output += \
                    " {node_index} Load({load}) Time({tmin}, {tmax}) -> ".format(
                        node_index=node_index,
                        load=assignment.Value(load_var),
                        tmin=str(assignment.Min(time_var)),
                        tmax=str(assignment.Max(time_var)))
          index = assignment.Value(routing.NextVar(index))

        node_index = routing.IndexToNode(index)  # Convert index to node
        load_var = capacity_dimension.CumulVar(index)
        time_var = time_dimension.CumulVar(index)
        plan_output += \
                  " {node_index} Load({load}) Time({tmin}, {tmax})".format(
                      node_index=node_index,
                      load=assignment.Value(load_var),
                      tmin=str(assignment.Min(time_var)),
                      tmax=str(assignment.Max(time_var)))
        print plan_output
        print "\n"
    else:
      print 'No solution found.'
  else:
    print 'Specify an instance greater than 0.'
def create_data_array():

  locations = [[82, 76],
               [96, 44],
               [50, 5],
               [49, 8],
               [13, 7],
               [29, 89],
               [58, 30],
               [84, 39],
               [14, 24],
               [12, 39],
               [3, 82],
               [5, 10],
               [98, 52],
               [84, 25],
               [61, 59],
               [1, 65],
               [88, 51],
               [91, 2],
               [19, 32],
               [93, 3],
               [50, 93],
               [98, 14],
               [5, 42],
               [42, 9],
               [61, 62],
               [9, 97],
               [80, 55],
               [57, 69],
               [23, 15],
               [20, 70],
               [85, 60],
               [98, 5]]

  demands =  [0, 19, 21, 6, 19, 7, 12, 16, 6, 16, 8, 14, 21, 16, 3, 22, 18,
             19, 1, 24, 8, 12, 4, 8, 24, 24, 2, 20, 15, 2, 14, 9]

  start_times =  [28842, 50891, 10351, 49370, 22553, 53131, 8908,
                  56509, 54032, 10883, 60235, 46644, 35674, 30304,
                  39950, 38297, 36273, 52108, 2333, 48986, 44552,
                  31869, 38027, 5532, 57458, 51521, 11039, 31063,
                  38781, 49169, 32833, 7392]

  data = [locations, demands, start_times]
  return data

if __name__ == '__main__':
  main()

Hey @Mizux, apologies. I tried using the following logic too, but Im unable to get the proper result. :
for vehicle_id in range(data['num_vehicles']):
    routing.SetArcCostEvaluatorOfVehicle(transit_callback_index_arr[vehicle_id], vehicle_id)

# Add Distance constraint.
dimension_name = 'Distance'
routing.AddDimensionWithVehicleTransits(
transit_callback_index_arr, # list of transit callback, one per vehicle
0,  # no slack
300000,  # vehicle maximum travel distance
True,  # start cumul to zero
dimension_name)
distance_dimension = routing.GetDimensionOrDie(dimension_name)
distance_dimension.SetGlobalSpanCostCoefficient(100)

# Define Transportation Requests.
for request in data['pickups_deliveries']:
    pickup_index = manager.NodeToIndex(request[0])
    delivery_index = manager.NodeToIndex(request[1])
    routing.AddPickupAndDelivery(pickup_index, delivery_index)
    routing.solver().Add(routing.VehicleVar(pickup_index) == routing.VehicleVar(delivery_index))
    routing.solver().Add(distance_dimension.CumulVar(pickup_index) <= distance_dimension.CumulVar(delivery_index))

are you using master or the the v7 beta ?

I think im using the master

hey @Mizux, I tried this approach too. But I'm getting an error when I put it in the Adddimension(). In this code, only the time aspect is relevant to consider the different vehicles.

def main():
  # Create the data.
  data = create_data_array()
  locations = data[0]
  demands = data[1]
  start_times = data[2]
  vehicle_capacity = data[3]
  num_locations = len(locations)
  depot = 0
  num_vehicles = 5
  search_time_limit = 400000

  # Create routing model.
  if num_locations > 0:

    # The number of nodes of the VRP is num_locations.
    # Nodes are indexed from 0 to tsp_size - 1. By default the start of
    # a route is node 0.
    routing = pywrapcp.RoutingModel(num_locations, num_vehicles, depot)
    search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

    # Callback to the distance function.

    dist_between_locations = CreateDistanceCallback(locations)
    dist_callback = dist_between_locations.Distance

    routing.SetArcCostEvaluatorOfAllVehicles(dist_callback)
    demands_at_locations = CreateDemandCallback(demands)
    demands_callback = demands_at_locations.Demand

    # Add capacity dimension constraints.
    #vehicle_capacity = 100;
    null_capacity_slack = 0;
    fix_start_cumul_to_zero = False
    capacity = "Capacity"
    routing.AddDimensionWithVehicleCapacity(demands_callback, null_capacity_slack, vehicle_capacity,
                         fix_start_cumul_to_zero, capacity)

    # Adding time dimension constraints.
    time_per_demand_unit = 300
    horizon = 24 * 3600
    time = "Time"
    tw_duration = 5 * 3600
    speed = [20,20,10,10,20]
    total_time_callback = []

    service_times = CreateServiceTimeCallback(demands, time_per_demand_unit)
    service_time_callback = service_times.ServiceTime
    for i in range(num_vehicles):
      total_times = CreateTotalTimeCallback(service_time_callback, dist_callback, speed[i])
      total_time_callback = total_time_callback+[total_times.TotalTime]
    print (total_time_callback)

    # Note: In this case fix_start_cumul_to_zero is set to False,
    # because some vehicles start their routes after time 0, due to resource constraints.

    fix_start_cumul_to_zero = False
    # Add a dimension for time and a limit on the total time_horizon
    routing.AddDimension(total_time_callback,  # total time function callback
                         horizon,
                         horizon,
                         fix_start_cumul_to_zero,
                         time)

    time_dimension = routing.GetDimensionOrDie("Time")

Hey @Mizux, Apologies for the inconvience. I tried another approach where I make a list of transit for each of the vehicles and then appended in the Adddimension command as follows. However, Im getting an error in the system. Can you please guide me through what Im doing wrong.
  if num_locations > 0:

    # The number of nodes of the VRP is num_locations.
    # Nodes are indexed from 0 to tsp_size - 1. By default the start of
    # a route is node 0.
    routing = pywrapcp.RoutingModel(num_locations, num_vehicles, depot)
    search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

    # Callback to the distance function.
    transit_callback_arr =[]

    dist_between_locations = CreateDistanceCallback(locations)
    dist_callback = dist_between_locations.Distance
    transit_callback = routing.RegisterTransitCallback(dist_callback)
    transit_callback_arr.append(transit_callback)

    for vehicle_id in range(num_vehicles):
      routing.SetArcCostEvaluatorOfVehicles(transit_callback_arr[vehicle_id], vehicle_id)

    demands_at_locations = CreateDemandCallback(demands)
    demands_callback = demands_at_locations.Demand

    # Add capacity dimension constraints.
    #vehicle_capacity = 100;
    null_capacity_slack = 0;
    fix_start_cumul_to_zero = False
    capacity = "Capacity"
    routing.AddDimensionWithVehicleCapacity(demands_callback, null_capacity_slack, vehicle_capacity,
                         fix_start_cumul_to_zero, capacity)

    # Adding time dimension constraints.
    time_per_demand_unit = 300
    horizon = 24 * 3600
    time = "Time"
    tw_duration = 5 * 3600
    speed = [20,20,10,10,20]
    total_time_callback = []

    service_times = CreateServiceTimeCallback(demands, time_per_demand_unit)
    service_time_callback = service_times.ServiceTime
    for i in range(num_vehicles):
      total_times = CreateTotalTimeCallback(service_time_callback, transit_callback_arr[i], speed[i])
      total_time_callback0 = total_times.TotalTime
      total_time_callback = total_time_callback+[total_time_callback0]
    print (total_time_callback)

    # Note: In this case fix_start_cumul_to_zero is set to False,
    # because some vehicles start their routes after time 0, due to resource constraints.

    fix_start_cumul_to_zero = False
    # Add a dimension for time and a limit on the total time_horizon
    routing.AddDimension(total_time_callback,  # total time function callback
                         horizon,
                         horizon,
                         fix_start_cumul_to_zero,
                         time)

    time_dimension = routing.GetDimensionOrDie("Time")

Sorry for so many questions @Mizux, but is it not working maybe cause I downloaded the OR tool from Binary https://developers.google.com/optimization/install/python/windows rather than downloading it from the source? Or am I just making a conceptual mistake


Provide a way to access total buffer size

I'm writing a vulkan renderer for imgui-rs and am need to determine what the total size of the vertex and index buffers are before starting each frame. This way it's possible to reallocate once at the beginning of the frame if the buffers aren't big enough rather than reallocating and copying once they fill up. It's possible to determine this by using the Ui::render method twice, but that's not really ideal.
Looking at a lot of the renderers that have already been implemented it looks like they rewrite the buffers on every draw call. The way I'm trying to implement this is so that it will just output the required draw calls into a command buffer, which can then be handled by the user of the library. Because of this, it's not okay for the buffer data to change in between draw calls, so the most obvious solution is to make one big buffer, fill it up at the beginning of the frame, and then use slices for each individual draw call. Doing this, however, requires knowing the total number of vertices and indices before starting to process draw calls.

Hmm, I'm a bit confused here: how could we know the total size of the buffers before the frame? We can't know what widgets will be drawn in advance, so how could we know the size?

The ImDrawData struct from imgui-sys has members total_vtx_count and total_idx_count, which are what I would need exposed in order to do this. Generally though, it would be nice to have an interface that gives more control than the current Ui::render.

And those fields are 0 during the frame until Ui::render calls sys::igRender. The total counts are available only after the entire UI drawing is done, so I don't understand what you want to do here.

determine what the total size of the vertex and index buffers are before starting each frame

This is the main source of my confusion: you're asking the total size of things but before the actual widget calls are done, so we have no idea how much stuff is going to be drawn. The point of time when things have stabilized so that you can know the total sizes is Ui::render (or ImGui::Render in the C++ world). Before that point of time, any widget call can end up resizing the draw list buffers.

Okay, that's a good point. The current implementation of Ui::render takes a closure which gets called on every individual draw list. What I want is something that can run after the ImGui::Render call in order to initialize buffers to the correct size, but doesn't get run on every draw list.

I made a pull request that changes the Ui::render closure to take one DrawData instead, so renderers now have access to the total counts and need to iterate the draw lists themselves. Does that look like a solution to your use case?


35601

Thanks

@35601  thnx for contributing , try this year aswell with updated repo and make sure to follow me and star this repo so that you don't miss updates regarding the new changes and issues during Hacktoberfest 2020.


Fix select dropdown with error UI

Html mistake:
instead of using the form-control class for dropdown, use the class custom-select


Need examples

Would be nice if we had a table that listed the available values that can be used for this property and what they mean.

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

ID: 4b62aefc-7ada-dbb7-cc0b-81cd16a2e1ee
Version Independent ID: b196487a-58e7-b137-2581-5bb4b60aaf57
Content: AutoFormatType Property - Business Central
Content Source: dev-itpro/developer/properties/devenv-autoformattype-property.md
Service: dynamics365-business-central
GitHub Login: @SusanneWindfeldPedersen
Microsoft Alias: solsen

Thanks for your feedback, yes we should get this content available. I will put this on our backlog. Thanks!

Hello, we have updated the article with more information. Hopefully this will help. The updated article will be published soon. Thanks for the feedback!


Indicate to admins when a profile section is not publicly visible.

Who is your user?

Collective and host admins.
What are they trying to achieve?

When looking at my collective/host's profile or the profile of a collective I host, I want to be able to tell what I am seeing that the public cannot, so I can not overlook the fact that, for example, a collective's budget is not visible to the public when it should be
How are they currently doing this?

Opening up the profile in an incognito window; but they will not do this if they don't know there is a problem.
I'm sure there are related issues, but I don't know of them.
How well understood is this problem?

[x] Surfacing: if you feel this is a seed of an idea that needs to be researched.
[ ] Understanding: if you've done some research and feel it is already well understood and ready for shaping.
[ ] Shaping:  if you feel a solution is clearly defined and can be made into a pitch (read more about shaping)
[ ] Pitching: if you feel that it is ready to be presented for prioritisation (read more about pitching)

To me, this is the main blocker for implementing something like https://github.com/opencollective/opencollective/issues/5426.


Istiod tests: input events record / playback

Create a harness that records all Inputs to istiod so that they can be played back later.
This feature is similar to traffic mirroring. Record must contain all config and registry changes.
Options.

Publish all incoming events to an event bus.

https://cloudevents.github.io/sdk-go supports kafka / NATS etc.
Write a cloud events subscriber to store events
write a cloud events consumer inside istiod to playback.

Use well known format, but always store to disk in a log format.

Disk log consumer as an input source.

Do we have a use case for "replaying" or do we just need to take point in time snapshot?

not stale.

@howardjohn replay is a good way to test our state machine in a deterministic way.


Update interface picture + slight minor fix in UG

Pull Request Test Coverage Report for Build 429

0 of 0 (NaN%) changed or added relevant lines in 0 files are covered.
No unchanged relevant lines lost coverage.
Overall coverage remained the same at 82.789%

Totals

Change from base Build 427:
0.0%

Covered Lines:
2689

Relevant Lines:
3248

💛  - Coveralls


jsxInject: Maybe not a good idea yet

The jsxInject is only implemented in vite, not in esbuild or anywhere.
The app code is not runnable in general without JSX imports, with @webpack or @snowpackjs.
https://github.com/preactjs/preset-vite/blob/b329a20ce9db3b1f4ae9312c175919e9d483d6a3/src/index.ts#L17
Maybe it is possible to comment out this option until it is supported by @evanw (esbuild) / @babel etc. itself.

https://www.typescriptlang.org/tsconfig/#jsxImportSource

I think a common way for all bundlers to do this would be to use the esbuild option.
In dev case add preact.shim and devtools.shim.
In prod case only preact.shim.
The shim file could be provided from the preact module self.
https://esbuild.github.io/api/#inject

I just came across this problem today. I'm pretty new to Vite, but fairly familiar with Preact. I am trying to add tests via Mocha, but with jsxInject being set in the plugin, it means my components can't have the import { h } from 'preact' in them. This leads to the following error in my tests: ReferenceError: h is not defined.
Is there some other way of going about solving the issue from the testing side? With my limited knowledge, I haven't found a solution. The only way I've been able to get both Vite and Mocha happy is to add a plugin that returns this block for the config esbuild:
esbuild: {
  jsxFactory: 'h',
  jsxFragment: 'Fragment',
  jsxInject: ''
}

For some reason just including that in the outer Vite config didn't work... I had to make it a plugin. This allowed me to get things working by manually adding import {h} from 'preact' at the top of my components.

Looks like the option will be deprecated shortly anyways, see https://github.com/vitejs/vite/issues/2369#issuecomment-846613927

With #18 being accepted you should be able to define/ overwrite the jsxInject string on plugin setup.


fix(CSI-236): for OCP installations, only 1 machineConfigPolicy was created

TL;DR
Fixed missing divider between YAML documents when created in loop, causing only last document to be applied.
What changed?
Added the missing separator
How to test?
ONLY on OpenShift cluster:
Ensure that when multiple machineConfigLabels are specified in values.yaml, a 50-csi-wekafs-selinux-policy-{label} is created for each label

[!WARNING]
This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

#295
#294  👈
#293
#286 : 3 other dependent PRs (#289 , #290 , #292 )
#291
#278
dev

This stack of pull requests is managed by Graphite. Learn more about stacking.

Join @sergeyberezansky and the rest of your teammates on  Graphite

Merge activity

Jul 31, 6:27 AM EDT: @sergeyberezansky started a stack merge that includes this pull request via Graphite.


hilbish: 2.1.0 -> 2.1.1

Automatic update generated by nixpkgs-update tools. This update was made based on information from https://github.com/Rosettea/Hilbish/releases.
meta.description for hilbish is: An interactive Unix-like shell written in Go
meta.homepage for hilbish is: https://github.com/Rosettea/Hilbish
meta.changelog for hilbish is: https://github.com/Rosettea/Hilbish/releases/tag/v2.1.1
Updates performed

Golang update

To inspect upstream changes
Impact

Checks done (click to expand)

built on NixOS
The tests defined in passthru.tests, if any, passed
found 2.1.1 with grep in /nix/store/31bbprk5bhxlgvlr2ddha1k66ymf77q0-hilbish-2.1.1
found 2.1.1 in filename of file in /nix/store/31bbprk5bhxlgvlr2ddha1k66ymf77q0-hilbish-2.1.1

Rebuild report (if merged into master) (click to expand)

1 total rebuild path(s)

1 package rebuild(s)

First fifty rebuilds by attrpath
hilbish

Instructions to test this update (click to expand)

Either download from Cachix:
nix-store -r /nix/store/31bbprk5bhxlgvlr2ddha1k66ymf77q0-hilbish-2.1.1 \
  --option binary-caches 'https://cache.nixos.org/ https://nix-community.cachix.org/' \
  --option trusted-public-keys '
  nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
  cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
  '

(The Cachix cache is only trusted for this store-path realization.)
For the Cachix download to work, your user must be in the trusted-users list or you can use sudo since root is effectively trusted.
Or, build yourself:
nix-build -A hilbish https://github.com/r-ryantm/nixpkgs/archive/9bc50177203fe489d83bafad6c711cc690a57a06.tar.gz

After you've downloaded or built it, look at the files and if there are any, run the binaries:
ls -la /nix/store/31bbprk5bhxlgvlr2ddha1k66ymf77q0-hilbish-2.1.1
ls -la /nix/store/31bbprk5bhxlgvlr2ddha1k66ymf77q0-hilbish-2.1.1/bin

Pre-merge build results
We have automatically built all packages that will get rebuilt due to
this change.
This gives evidence on whether the upgrade will break dependent packages.
Note sometimes packages show up as failed to build independent of the
change, simply because they are already broken on the target branch.
Result of nixpkgs-review run on x86_64-linux 1

1 package built:

hilbish

Maintainer pings
cc @fortuneteller2k for testing.

Closed by #226308.


Create Discord server

Need to create a server. We need to make sure:

have an organisers channel
have a mentors channel
general channel
one-click use invite link only

Also need to make sure we have good enough moderator capabilities

@nnja Made me aware of the Python Discord server. So we were discussing if it would be a good idea to use this for the mentored sprints as this already has a lot of members and a help channel.
This is open for discussion and we might then need to contact the admins to see if we could piggy-back on this server

Hey I am in the Python Discord server as well, but I am never active there.
Reason for not using that is 1. we do not have full admin right to the server 2. It may be a bit overwhelming for people not familiar with Discord to start using that server because it's size and complex structure.
Reason for using would be 1. if we got support from their admin they can set up everything Discord related for us 2. Publicity 3. support form their community

@nnja do you know the admin? If so could we ask them to use the server?

I think whatever the decision is we need to move fast and have this created / sorted for when I send the final details to folks. Ideally wanted to notify everyone tomorrow  or Wednesday

Maybe we should set up a server anyway? I can help with that. Have some
time this evening if @Tania you wanna set up today.
Cheuk
On Mon, 11 May 2020 at 18:05, Tania Allard<EMAIL_ADDRESS>wrote:

I think whatever the decision is we need to move fast and have this
created / sorted for when I send the final details to folks. Ideally wanted
to notify everyone tomorrow or Wednesday
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
https://github.com/pycon-mentored-sprints/organisational/issues/36#issuecomment-626829372,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AG3N26OA75VX5TFWE4LIP6DRRAV43ANCNFSM4MO6IHFQ
.

@trallard @Cheukting yes, the admins reached out to me about a different topic, so I have a direct line to them. So far they've been incredibly friendly and helpful.

the pros/cons:
pros:

there's additional ways to get help and tons of topic channels
we'll be funneling participants into an already active community. I imagine activity in our discord will die down in the days/weeks after the event.
the server and avenues for long-term moderation are already in place. For our own discord, we'll have to think about long term moderation.

cons:

It's a big server and might be too much / overwhelming for someone new to discord.
This idea is definitely contingent on the mods supporting us and our idea

If we make our own discord we should think a bit about what we plan on doing with it after the event is over. Do we try to keep the space open? If so, are we able to provide resources for long term moderation? Or do we want to shut down the server a week or two after the event to prevent additional administrative burdens?

Great to hear @nnja, here are my thoughts:

I think maintaining a server post mentored sprints would be quite a lot of extra work. I personally cannot commit to long term support on yet another community platform
Though the existing server might be daunting it might also be a way to introduce folks to the community and provide them with a platform they can turn to for help during/after the sprints

Any chance you could ask the mods and see if they'd be happy to add us?

Done - created Mentored sprints server which will be long-term shared and maintained by Python sprints (@Cheukting ) and scikit-learn sprints


Handle aggregator dtypes in a more systematic and sensible way

This is a continuation of https://github.com/metagraph-dev/grblas/pull/87

:tada:
Btw, argmini and similar were dropped in the end.  argmin does the expected thing, but doesn't work with matrix.reduce_scalar.


fix width of uncertainty value

Match the width of the uncertainty value with the C++ version. It's very very improbable that this could cause a problem, but it's hypothetically possible for a value to get out of range and cause a difference.

Realized that this can't happen


adaptive charging missing

i am using PE+ with June Security update. after flashing the module I don't see any new toggle in battery settings to turn on adaptive charging. my device is a K20 btw

Yes it won't work


fix for #279 (inline keyword must not be macroized when building C++ code)

Adds a configurable macro for the inline keyword, later defined as 'inline' for C++.

Thanks for your PR. However we chose to fix it in a different way, see 0223ab9


ability to turn off call home and sync to backend functionality

Paranoid people would appreciate the ability to turn off all network functionality.

Agreed! This is in the works and is being tracked in #4.


Add instructional text to main view.

Add instructional text in the empty view pane (or Main Stage / Main View? - how should we name this/ ).
Use example from Operations Dashboard:

added. closing


branchOrder not written to nc file

Describe the bug
branchOrder not written to nc file.
To Reproduce
Steps to reproduce the behavior:
in net\models.py on line 775: self.network1d_branch_order = np.append(self.network1d_branch_order, -1)
The branchOder is always appended with -1.
Expected behavior
branch_order is passed to the function as an input argument. It should be used here
in net\models.py on line 775: self.network1d_branch_order = np.append(self.network1d_branch_order, branch_order)

Issues is already merged to main


Fix formatting of wrapped errors when colors are used

There are two different code paths for rendering a key/value pair. The
non-color version uses a type switch that handles specific types such as
"error", and the color version uses the %+v printf format specifier.
This causes an inconsistency between the two formats. In particular,
errors created using the github.com/pkg/errors package will include a
stack trace of where the error was created when printed to the terminal,
but not to a file. Printing the stack trace as part of the log field is
probably not the right behavior.
The output is also inconsistent between the two forms because strings
are not quoted/escaped when colors are used. This can make log output
unparseable.
Fix this by making both code paths use the type switch and escaping
rules. Fix the escaping code to pass the error value to Fprintf, not the
error itself, which seems to be necessary to avoid blank output with
errors created by github.com/pkg/errors.

ping @Sirupsen could you have a peek at this one? :heart:

@aarongreenlee

ping @aarongreenlee (sorry for the repeated ping, but would be great if this was merged before our docker 1.13 code freeze)

Released as part of 0.11.0

Thanks @Sirupsen ❤ !

@thaJeztah @aluzzardi is anyone from Docker Inc interested in helping out with some ownership of Logrus? 🎉

@Sirupsen I can discuss the option 👍

@thaJeztah awesome, let me know! I feel so guilty for not being able to respond quicker here.


[storage-resize-images] Ability to specify file type for thumbnails

[READ] Step 1: Are you in the right place?
Yes
[REQUIRED] Step 2: Extension name
This feature request is for extension: storage-resize-images
What feature would you like to see?
I would like to be able to override the file type of the thumbnails.
How would you use it?
Someone may upload a JPEG or GIF that I want to keep in its original format so it can be downloaded in the future, but I want to normalize all the thumbnails to to PNG.

Hi @Soviut.
In later versions of the extension, while installing you will be provided with a number of options for file types.
For your scenario, you can select original and png.
Additionally, if you would like to keep the original file that has been uploaded, please select No when asked Delete on successful resize.
Please let me know if that has answered your question

@dackers86 Thanks. I feel like the help text in the web ui could be clarified.

Convert image to preferred types:
The image types you’d like your source image to convert to. The default for this option will be to keep the original file type.

The problem I had was that it kept mentioning the "original file" and "original file types". It might be worth rewording that to just say "destination file types".

Thanks @Soviut
You're correct, this documentation could do with an update.
I'll update to under consideration.

Hey @dackers86 , is there a way to specify output type for given input file types?
My use case is that I want to convert everything to a png, except for gifs which should essentially stay in a gif format.

Hi @TangrisJones
I agree this is most likely a new of issue/bug, could you create a separate bug/issue?
This would be much easier track and investigate. Thanks!


Question - unhandled promise rejection in .on callback function

Is there any other way / good practice to handle promise rejections inside event emitter function? I would like to get rid of the try..catch. But when removing them, the unhandled promise rejections are not given back to the calling asyncSubscribeToMultipleEvents.
Currently I call a wrapper asyncSubscribeToMultipleEvents to subscribe
/// async wrapper, status and error handling
    asyncSubscribeToMultipleEvents(node, subscriptions, player)
      .then((success) => {
        node.status({ fill: 'green', shape: 'ring', text: 'connected' })
        node.debug(`success >>${JSON.stringify(success)}`)
      })
      .catch((error) => {
        node.status({ fill: 'red', shape: 'ring', text: 'disconnected' })
        node.debug(`error >>${JSON.stringify(error, Object.getOwnPropertyNames(error))}`)
      })
....
}

and then
async function asyncSubscribeToMultipleEvents (node, subscriptions, player) {

    async function sendAlarmClockMessage (raw) {
      try {
        debug('new AlarmClockService event >>', JSON.stringify(raw))
        const alarms = await player.AlarmClockService.ListAndParseAlarms()
        const payload = raw
        const topic = `household/${player.host}/alarmClock/alarmList`
        const msg = [null, null, null, null, null]
        msg[1] = { payload, alarms, topic }
        node.send(msg)
      } catch (error) {
        node.status({ fill: 'red', shape: 'circle', text: 'error' })
        // eslint-disable-next-line max-len
        node.debug(`error during execution of event >>${JSON.stringify(error, Object.getOwnPropertyNames(error))}`)
      }
    }

    // bind events
    if (subscriptions.alarmList) {
      await player.AlarmClockService.Events.on('serviceEvent', sendAlarmClockMessage)
      debug('subscribed to AlarmClockService')
    }
...
}

You can also add .catch((err)=> console.warn(err)) that will make sure it won’t error out.

You can also add .catch((err)=> console.warn(err)) that will make sure it won’t error out.

I was not precise enough. What I meant: Is there a way to hand over  a rejected promise to the routine where the event handler is set up. The try/catch or .catch() - if there are only a few critical command - are ok. So we can close this.

I was not precise enough. What I meant: Is there a way to hand over  a rejected promise to the routine where the event handler is set up. The try/catch or .catch() - if there are only a few critical command - are ok. So we can close this.

I was not precise enough. What I meant: Is there a way to hand over  a rejected promise to the routine where the event handler is set up. The try/catch or .catch() - if there are only a few critical command - are ok. So we can close this.

I was not precise enough. What I meant: Is there a way to hand over  a rejected promise to the routine where the event handler is set up. The try/catch or .catch() - if there are only a few critical command - are ok. So we can close this.


Add unit test coverage for the ASP.NET WebAPI integration project

We need test coverage on this project.

Fixed, with initial test coverage. More tests are needed, but the issues filed need to be more specific and based around code coverage.


charan.md

[x]  additional info
[x] open GitHub pages
[x] open Git

I am completed these three tasks

hello


HDT needs .net 4.7 now.

WINEPREFIX=~/wine.hs wine ~/Downloads/HDT-Installer.exe
does give you the option to install it for you, however it does seem to hang at some point @ Downloading netfx_Full_x86.msi ... dunno... will wait. Maybe it will finish at some point.
emm nope. and if you do install dotnet472 with winetricks, then the HDT installer just crashes with new wine-staging 5.7.

The tips provided here worked for me
https://github.com/HearthSim/Hearthstone-Deck-Tracker/issues/4055

Thank you! Got it sorted now. Downgrade to wine-staging 5.8, avalon.graphics thing added works.
Just for info into your readme, in Xfce with Xfwm4 also only windowed mode works with overlay.
Also I believe you don't need to set the win7 anymore as installing dotnet472 does it for you.

I forgot to close this, the instructions have been updated.


Github pages + API reference

Okay so this is no documentation, but it can help find what's available etc.
So take a look, and if you like it, that'd be great.
Things added in this PR:

API Reference  (this will generate pages like https://thewolfnl.github.io/parable/docs )
Using github pages (this will generate a page like https://thewolfnl.github.io/parable/ )

To generate the API reference just call vendor/bin/apigen generate and it will update the docs/ directory.

Haha, that's awesome, man! Thanks for the PR :)
I'll be looking into this sort of thing more once the 0.11.x branch is getting close to being finished. I'll leave this PR open and revisit it by then.

Yesterday I came across https://www.phpdoc.org/ (dóh) and that looked nice as well, but could also try to figure that one out.

Yeah, I was looking into that one as well. There's multiple options, but I hadn't looked at ApiGen yet, so by the time I've nailed down the API I've got some comparing (and additional commenting) to do :D

Main reason I used apigen, is because I didn't read properly, thinking phpdocumentor needed PEAR and stuff, but I just noticed that using composer would be okay as well.
Do you want me to create a phpdocumentor branch for the 0.11.x?

I can't stop you, but I will say that I'm rather picky about the kind of documentation I myself prefer to see, and it usually isn't an API reference :)
Think more like Laravel's docs, with examples and additional information. I've been working on it, actually, but with the API changing significantly in 0.11.x, I've taken a break until it solidifies a bit.
Just want to make sure you're not spending time on something I might not end up using :)

Fine by me 😛 Let me know If you do want to add the API reference

Oh, you'll know :D

Now that 0.11.0 is out, I'm closing this. The suggestions aren't forgotten, though, and will be taken into consideration when the documentation writing process starts. Don't think an API reference of some sort would hurt 🙂


Ignore changes of path.module

${path.module} is unique for every terraform checkout. Every time I apply this module after someone else there are spam associated with template_dir's source_dir.
This change silences the diff warning as suggested by https://github.com/hashicorp/terraform/issues/7613.

@miry This seems to not work at all, we just talked with @alvelcom on chat. It does work for you doing any other step? Can you please share what works that didn't before with this patch?


Multi browser location/apps

If on client side there is 2 chrome browsers, standalone or some another instance is it possible to provide "that" chrome PID or location to catch exactly "that" chrome session - at now as i see - nope.

it is designed to work the default chrome and default chrome path. if you want to add other browsers or browser version you are free to modify it, all that the browser cloning is just copying the data directory of the browser to another location then starting the browser defining that copied location as the data directory (in command line args). i may add in the future a mass scan of all browsers then allowing the user to select which one they want to clone in a later update. but for this moment its not going to be added, but in the future prob.

(didnt meant to close it)


Prevent divide by zero

This happens when the number of hits is less than the number of splits per shard.

Good catch. Thanks for the contribution!


Assign a colors to each pointers

I'm using the client id as a random number to index on the color array. So far it's been working better than using a sequential increment as the colors in the array are sorted by proximity. Also, it has the advantage that everyone in the room will see the same color for the same person.

Beautiful!

Next thing: Showing names next to the cursors.. :)
(Not sure how the UI should be for this one though)


full screen not working

When a full screen is attempted, though the screen goes full and black, the image reduces to a tiny upper left corner coloured dots...
It's like that for about last 2 or 3 releases.

Which version are you using? Is it v0.3.1 or version from tip of the master branch?

v0.3.1

Very similar issue (#229) was solved recently, but changes were added after v0.3.1 release.
I've just put another tag, v0.3.2. Please try it (or version master branch, they are the same at the moment).

Though I do not use KDE (neither any DE), but rather plain Fluxbox WM, It worked out!
And as I use Arch, I just had to "yaourt -Sayu", and got the new package version, :-)
So you can close this.
Thanks a lot,

Issue wasn't caused by KDE exclusively. Just PepperFlash was updated and its behavior slightly changed. Together with differences in going-to-full-screen procedure in different window managers that triggered a dormant bug. It's still there, by the way. I just hope 300 ms is enough to open fullscreen window for any WM. (Delay can be changed via editing of configuration file.)
Ideal solution would be to accept all size changes in PepperFlash, not only the first one. But since its code is closed, the only way solve it is to workaround it.

OK, great support Rinat...  And thanks a lot.


Make sure Andy and Alicia's PSCIS entry gets added to main gpkg in 2023/data_field/form_pscis_2023.gpkg

Since they are two separate files, will have to read in both and bind rows. Ensure photos are sorted as well.

Photos are all sorted to their appropriate folder. Just did it by hand since there was only a few. They were all under 1mb already too.


SYM-624: List compound comparisons in UI

Renders a list of the logged in users' "compound comparison" entities in the UI.
Also exposes a button to delete each entity.
The list is (atypically) rendered in a dialog box instead of in a side panel.
The reason for this divergence may be found in the case details for SYM-624.
PR also contains three strictly unrelated "housekeeping" commits (db724ae, 61eb51f, 14419f0).

NB. Pedantic previous "force push" was only amending the commit reference, in the comment for the previous commit.

Minor note - the comment on commit da0a1e3 mentions RFC7231, which is an obsolete version of RFC9910 (HTTP Semantics).
Should probably have put 'HTTP semantics' 🤷♀


Control multiple air works using multiple threads

Goal

Control multiple air works using multiple threads via pressure control actionlib
For example, A single pump is used for

adsorption of the robot base to the wall surface and
for object grasping by the robot arm.

Problem

Assume Air_Work_A and Air_Work_B start at about the same time and Air_Work_A finishes before Air_Work_B.
The Air_Work_A controller turns off the pump as soon as Air_Work_A is finished, but this prevents Air_Work_B from being completed.

This PR

Add MultiLock class to restrict access to commonly used pump and solenoid valve
Control multiple air works using MultiLock

Note
If you control only one air work, there is no change.

Sample code:
$ roscd kxr_controller/scripts
$ python3 interface.py
In [2]: test(ri)

def test(ri):
    # Start air work
    ri.send_pressure_control(
        board_idx=int(39),
        trigger_pressure=-10,
        target_pressure=-30,
        release_duration=0
    )
    rospy.sleep(0.1)
    ri.send_pressure_control(
        board_idx=int(40),
        trigger_pressure=-10,
        target_pressure=-30,
        release_duration=0
    )
    rospy.sleep(1)
    # Release air
    ri.send_pressure_control(
        board_idx=int(39),
        trigger_pressure=-10,
        target_pressure=-30,
        release_duration=2
    )
    rospy.sleep(0.1)
    ri.send_pressure_control(
        board_idx=int(40),
        trigger_pressure=-10,
        target_pressure=-30,
        release_duration=2
    )

I have confirmed that it does not affect the pressure control mode when using one air work.


Cannot distinguish between event handlers when doing drag-n-drop

Hi,
I am back :)
I've used the following markup to cover both drag-n-drop and usual selection for multiple file upload:
<ngx-mat-dropzone (drop)="onDropDocuments($event)">
    <input type="file" fileInput [ngModel]="files" [ngModelOptions]="{ standalone: true }" [multiple]="true"(ngModelChange)="onSelectDocuments($event)" />
</ngx-mat-dropzone>

Unfortunately, it works well only for an ordinary select, because only onSelectDocuments is triggered. When I use drag-n-drop, both onSelectDocuments and onDropDocuments handlers are triggered and as a result, I get the issue, because the code has to process the same logic twice. How to avoid this and clearly divide the handlers?
I used some custom logic, that's why I use onDropDocuments handler. And also I found using ngModel in my case instead of formControl to be preferrable.
In fact, the main reason for having the custom code was to get the initial source path of the file by all means, since we needed to pass this info to server. If I could obtain this information in other way, probably I would get rid of the issue as well by eliminating some custom handlers...

Hi.
I use my custom logic in onDropDocuments method to handle a drag-n-drop scenario. This logic creates the collection of files to-be-uploaded, filling the original file path using FileSystemEntry => fullPath property (otherwise the original file name does not contain this information). Here, I have to copy the original file to a new file to change its name, because File is immutable (this.files.push(this.copyFile(file, fileEntry.fullPath.replace(/^\/[A-Z]_drive/, '')));)
And I use onSelectDocuments to handle an ordinary logic - selecting files folder with standard system "Open" button - in this case the original file path is available straight in File => name. In general, I use onSelectDocuments to build a common logic of displaying the files to-be-uploaded (the folder structure with the total amount of files and its volume per each subfolder), no matter if it's a drag-n-drop or a system select.
And I am getting issues related to the fact that for drag-n-drop both methods are called. So I would appreciate your proposals how to simplify my logic to still achieve the goal.
The team member broke the page availability and I cannot test my page right away. Are you implying that I can use webkitRelativePath next to webkitdirectory and it will resolve my issue and besides I will be able to through away some of my code?

Please have a look at PR #80. This might fix your problem.
I first decided to ignore the relative path info, but I thinks it's time to add it back in.
The only way to achieve a consistent behavior is to add a new property.
Please review the PR code. You might want to checkout the branch and try it locally.
If this fits your needs, we may release a new version.

Thank you. Sorry, don't know what is the correct way to check your changes. I've installed GitHub Desktop, still cannot see how to use your PR code...

After cloning the repo and npm install follow these steps to run a test app.
Then upload some files and check if the relativePath property is set. You should be able to keep the file paths on drop AND when using the file picker.
Migrating to Angular 18 is recommended anyway, as a workaround you could install the latest version with --force flag in your project.
About your other question, the internal state is stored in the value property.
I would recommend to use a FormControl for the most flexible state management.
Use the property mode (see config) to change the behavior. By default, a second file selection will overwrite the first one. But you may also "stack" all selected files.

Hi Paul.
Thank you, I've installed PR version to my project.
Seems like it does not work fully correct or I am missing something.
Here is my usage (for "folder selection" scenario):
                <ngx-mat-dropzone>
                  <input type="file" fileInput [(ngModel)]="files" [ngModelOptions]="{ standalone: true }" [multiple]="true" relativePath mode="append" webkitdirectory (ngModelChange)="accumulateFilesAndRecalculateFolders($event)" />
                </ngx-mat-dropzone>

When I select the folder in a system way, via button click - everything looks as expected.
However, when I drag-n-drop - webkitRelativePath property is still zero (and file name contains only name, no path info either).
Another issue: I have the button to remove the selected files, which does this:
this.files = [];
However, when I select the files again, it pulls the previously selected files from somewhere...

Hey, thanks for the feedback.
You're almost there. On drop, the webkitRelativePath property will be empty, since I can't overwrite it with the full path value because it's readonly. Therefore, I added the new relativePath property which should have the expected value.
As for your other bug of clearing the array, I will have to look into this in the next few days. Maybe use a FormControl as a workaround?
When using mode="replace" (which is the default) on the <input type="file"> element, no duplicates should be possible because the files array will be reset on each change. Any other validation will be left to you as the consumer. You might check for duplicate file names in the FormControl valueChanges handler.

Maybe I am missing something obvious, but on drag-n-drop console.log((file as any).relativePath) returns me undefined...

Maybe use a FormControl as a workaround
I might check it out later on, but if it was possible to make it work for ngModel, I would be happy ;)

Okay, so let's try to figure this out.
Please setup the local playground dev app as described in my previous post. With this minimum example I got it working as expected.
import { Component } from '@angular/core';
import { File } from '@ngx-dropzone/cdk';

@Component({
  selector: 'app-root',
  template: `<div class="app-container">
    <mat-form-field appearance="fill">
      <mat-label>Drop anything!</mat-label>
      <ngx-mat-dropzone>
        <input
          type="file"
          fileInput
          multiple
          webkitdirectory
          [(ngModel)]="files"
          [ngModelOptions]="{ standalone: true }"
          (ngModelChange)="buildFolderOutput()"
        />
      </ngx-mat-dropzone>
    </mat-form-field>
  </div>`,
})
export class AppComponent {
  files: File[] = [];

  buildFolderOutput() {
    this.files.forEach((f) => console.log(f.relativePath));
  }
}

To be able to reset the internal value, even with mode="append", I expanded the PR to add a new clear() method to the directive. Use it like so.
<input type="file" fileInput #fi="fileInput" mode="append" />

<button (click)="fi.clear()">Reset</button>

Thank you, i will try this on Monday. Quick question: is it possible to delete a single item from files array? I should have asked that from the start, not deleting all elements, sorry.

Yes, if you have set mode="replace" you can just update your files array.
this.files = this.files.filter(f => f.name !== "test");

Yes, if you have set mode="replace" you can just update your files array.
this.files = this.files.filter(f => f.name !== "test");

Well, I prefer this.files.splice(index, 1) - I think it might be faster... But anyway, the deletion is OK.
So underlining, the latest version works. Small note: to remove all the elements, I really need to use clear method, otherwise (if I do this.files = []) it still retains the old value which seems a bit weird to me.
All other things work, thank you very much!

Hi. I've compiled the latest version and still observe the bug.
Step to reproduce:

Drag file 1; Result: file 1 appears in UI;
Drag file 2: Result: file 2 appears in UI, but also file 1 appears in UI again - duplicate.

Looks fine now. Could you please publish the version?

I want to interfere with the default Browser behavior as less as possible. Therefore, I will leave the handling of this edge case to the consumer (n this case you), depending on the use case.
I will now merge the PR and release a new version that you might want to pull into your project.

Hi, @hackingharold.
I occasionally found out, that relativePath does not work anymore as it worked before - at least, on the latest version of Chrome.
Here is the source file:

Please have a look - this is what is looks like when I drag-n-drop a file:

And here is what it looks like when I use a standard "open" way:
.
If I use webkitdirectory attribute on other page, where I need to select a whole folder - it does not look right either, you can check it out yourself...

Hey,
I just tested this with<EMAIL_ADDRESS>in Chrome 126 using my StackBlitz example and it's still working as expected.
Note that the webkitdirectory attribute is required to be able to get the relative path when using the native file picker.
Please provide some more information if you cannot get it to work.

I am confused now, your example is working as expected for me.
Please see the following table and explain what you expect differently:

webkitdirectory ❌
webkitdirectory ✅

selecting file(s) from file picker
relativePath is empty because no directory was selected
not possible, forbidden by Browser

selecting folder from file picker
not possible, forbidden by Browser
relativePath is set based on selected folder

dropping file(s)
relativePath equals the name because no directory was selected
relativePath equals the name because no directory was selected

dropping folder
relativePath is set based on dropped folder
relativePath is set based on dropped folder

For the file picker, you have to decide to either allow folders or single files by setting the webkitdirectory attribute. This is native Browser behavior I cannot do anything about.

Thank you, I understand now... A directory selection mode works well, you are right - my bad (indeed - it's RELATIVE path, not ABSOLUTE :)).
Regarding a file selection mode, which now I am coping with... So, to your knowledge, there's no any way to find out an absolute source path of the file to be uploaded via javascript?

Thank you so much.

One more question: how to differentiate between the previously added files and a new chunk - the files which are being added now? I've tried to use formControl for that:
this.files.valueChanges.subscribe((files) => ...) // this.files is formControl as in your example
expecting that "files" parameter would contain only the current chunk, but it contains WHOLE collection...
I need the differentiation, because I add some custom form controls accompanying the files to be uploaded.


Added restart policy to all services that didn't have one

Also updated the policy of the services that had restart always to restart unless stopped.

@jofmi there you go


Chrome tabs gone when dragged

I'm running macOS High Sierra 10.13.6 (17G65). chunkwm is 0.4.6 release, compiled myself.
Steps to reproduce

Set global desktop mode to BSP
Open Chrome, open a few new tabs
Click and drag a tab out

Normally I would expect by dragging out a tab, a new Chrome window is created with the only tab. But under chunkwm, the new Chrome window comes with no tabs at all (the page is there, just not the tab), so I cannot drag it back anymore.

I’ve seen this as well. Hasn’t been a deal-breaker, but am interested in why it happens.

I've found that sometimes you can force it to fix itself with interacting with the chrome of the window (no pun intended) in specific ways. I hit command+f to open the find dialog and that usually does the trick. Don't think we can do anything on chunkwm side. See https://github.com/koekeishiya/chunkwm/issues/274

While your suggestion is likely able to fix the issue, this would require us to be able to queue operations that are going to be performed to the window tree, so that we can process this action at a later stage when the left mouse button is no longer down (or whatever criteria that event would set).
Disregarding the queue-system, I also think there would be a lot more false positives if we were to introduce a basic check that said "if left-mouse is down, ignore window_creation events that would add a window to the window-tree".
I don't think an issue only occurring with chrome is worth the time and potential failure-points that such a system could introduce. It is not something I am very keen to address personally at least.


Can't upgrade to versions above 0.103.0 (BT related?)

Home Assistant release with the issue:
103.x

Frontend
20191204.1 - latest

Last working Home Assistant release (if known):
0.103.0
Operating environment (Hass.io/Docker/Windows/etc.):
Hass.io
(Intel-Nuc image)
Integration:

Description of problem:
Found a way to upgrade; See additional information.
(Don't know if it's related to https://github.com/home-assistant/home-assistant/issues/30060)
I cant upgrade to version above 0.103.0. Everytime i try it fails and roll back. I can manually up/downgrade to any versions as long as its not above 0.103.0.
Log file log.txt
Versions tried:
0.102.0 working
0.103.0 working
0.103.0b0 working
0.103.1 failing
0.103.2 failing
0.103.3 failing
Error message:
19-12-21 12:11:48 WARNING (MainThread) [hassio.homeassistant] Don't wait anymore of Home Assistant startup!
19-12-21 12:11:48 CRITICAL (MainThread) [hassio.homeassistant] HomeAssistant update fails -> rollback!
19-12-21 12:11:48 INFO (MainThread) [hassio.homeassistant] Update Home Assistant to version 0.103.0
19-12-21 12:11:48 INFO (SyncWorker_0) [hassio.docker.interface] Update image homeassistant/intel-nuc-homeassistant:0.103.3 to homeassistant/intel-nuc-homeassistant:0.103.0
19-12-21 12:11:48 INFO (SyncWorker_0) [hassio.docker.interface] Pull image homeassistant/intel-nuc-homeassistant tag 0.103.0.
19-12-21 12:11:50 INFO (SyncWorker_0) [hassio.docker.interface] Stop homeassistant application
19-12-21 12:11:50 INFO (SyncWorker_0) [hassio.docker.interface] Clean homeassistant application
19-12-21 12:11:50 INFO (SyncWorker_9) [hassio.docker.homeassistant] Start homeassistant homeassistant/intel-nuc-homeassistant with version 0.103.0
19-12-21 12:11:55 INFO (MainThread) [hassio.homeassistant] Home Assistant pip installation in progress
19-12-21 12:12:20 INFO (MainThread) [hassio.homeassistant] Home Assistant pip installation done
19-12-21 12:12:27 INFO (MainThread) [hassio.auth] Auth request from core_mosquitto for mqtt_user
19-12-21 12:12:27 ERROR (MainThread) [hassio.homeassistant] Error on call http://<IP_ADDRESS>:8123/api/: Cannot connect to host <IP_ADDRESS>:8123 ssl:None [Connection refused]
19-12-21 12:12:27 INFO (MainThread) [hassio.auth] Home Assistant not running, check cache
19-12-21 12:12:27 INFO (MainThread) [hassio.auth] Cache hit for mqtt_user
19-12-21 12:14:25 INFO (MainThread) [hassio.homeassistant] Detect a running Home Assistant instance
19-12-21 12:14:25 INFO (MainThread) [hassio.homeassistant] Successful run Home Assistant 0.103.0
19-12-21 12:14:25 INFO (SyncWorker_2) [hassio.docker.interface] Cleanup images: ['homeassistant/intel-nuc-homeassistant:0.103.3']
19-12-21 12:15:42 INFO (MainThread) [hassio.homeassistant] Updated Home Assistant API token
19-12-21 12:17:28 INFO (MainThread) [hassio.auth] Auth request from core_mosquitto for mqtt_user
19-12-21 12:17:28 INFO (MainThread) [hassio.auth] Success login from mqtt_user

Problem-relevant configuration.yaml entries and (fill out even if it seems unimportant):

Traceback (if applicable):

Additional information:
By disabling bluetooth and bluetooth_le device tracker i was able to upgrade to 0.103.3. At no point check config is catching any errors, but it seems related to bluetooth...

I have the exact same issue.

@foxpyre

By disabling bluetooth and bluetooth_le device tracker i was able to upgrade to 0.103.3. At no point check config is catching any errors, but it seems related to bluetooth...

Yes, I followed your advice and it worked right away, thank you!

@foxpyre your welcome 🙏

Now on 0.103.3 i can't reboot host with bluetooth and bluetooth_le enabled. It's not booting until they are removed again.

In my case 0.104.0b0 fixes this issue. I keep it open because of others mentions this issue, feel free to close 🙏

Since this issue has been solved, I will close it. If anyone still has this error you can comment on here and we can reopen it, hope you understand :)


What about adding an option to disable command repeat (on Enter key)?

Your proposal
It's a minor thing but it would be nice to have an option to disable command repeat when the Enter key is pressed in debug console.
Additional context
For users coming from pry it could be confusing to have the repeat feature on Enter.
Also, IMO, it's not comfortable repeating some commands that have side-effects. Ex. SomeModel.create! name: 'A test'

I could try a PR if you like.
Perhaps it could be something like updating this point:
https://github.com/ruby/debug/blob/master/lib/debug/session.rb#L407
to:
@repl_prev_line = line unless ENV['RUBY_DEBUG_NO_REPEAT_ON_ENTER']

It is useful for step/next/... and so on
I also understand the Ruby script like SomeModel.create! name: 'A test' is not confortable.

Your request is adding new option to stop the repeating the command, but another option is don't repeat Ruby script.
I'm okay for that.

#793 limited the repeatable commands, like step, next, ... and Ruby expression is no longer repeated with empty line.
If you feel inconvenience with it, please reopen or renew an issue.


Validate tool checks per-point time stamps.

Checks for per-point timing issues in a bag file.
Feature is tracked in #529.

@wally-the-cartographer merge

Merge requested by authorized user gaschler. Merge queue now has a length of 1.


Custom Override Middleware w/example

Description
[Pull Request Description Here]
Type of change

[ ] Bug fix (non-breaking change that fixes an issue)
[ ] New feature (non-breaking change that adds functionality)
[ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)

Related issues

Fix [#1]()

wanna merge this so we can do a release tonight?


This app is detected by Google as Malicious software

This might not be a bug, but for unknown reasons, utterance is detected by Google as a malicious software. My website jyutping.org uses utterance, and Google Ads just banned it for having malicious links and software. I was confused and asked Google why. They replied:

I searched through my codes and the only reference I can find is the <script src="https://utteranc.es/client.js" in my html. So this utteranc.es is a malicious link?

I'm happy to help any way I can, everything looks fine on my end:

Ask them if there's another verification process I need to follow for https://utteranc.es

@jdanyow Thanks! According to Google's explanations here, a site may still contain malicious link even the search console doesn't report any problem:

I have scheduled a call with Google ads support next week, and will post updates here if I have any new information.

I just talked to google ads support, they say that they do not have the expertise to determine why this link is recognized as a malicious link. I was very confused and asked why they tag it as malicious if they don't have the expertise? The support said the analyze is done by another team and according to the policies in Google they don't provide any other information. The support said she recommend to find a webmaster to analyze the webpage so as to find out why it is malicious.

I am not sure if I should go ahead to hire a webmaster or simply remove utterance from my site. Please feel free to close this issue.

The support said she recommend to find a webmaster to analyze the webpage so as to find out why it is [considered] malicious [according to Google's unknown criteria].

That sounds like an impossible problem to me.
I understand the value of security by obscurity, but you are trying to help Google by showing them that their malicious website classifier is incorrect, and they don't seem to care.


add new vendored grpc version

Add new vendored grpc version.  Is the same as previous with grpc-alts added to the grpc vendored dependencies.
Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:

[ ] Mention the appropriate issue in your description (for example: addresses #123), if applicable. This will automatically add a link to the pull request in the issue. If you would like the issue to automatically close on merging the pull request, comment fixes #<ISSUE NUMBER> instead.
[ ] Update CHANGES.md with noteworthy changes.
[ ] If this contribution is large, please file an Apache Individual Contributor License Agreement.

See the Contributor Guide for more tips on how to make review process smoother.
To check the build health, please visit https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md
GitHub Actions Tests Status (on master branch)

See CI.md for more information about GitHub Actions CI or the workflows README to see a list of phrases to trigger workflows.

r: @Abacn


Twig.parse did not always return a string

Because parse directly returns Twig.output which can return either a String
or a string you never know which of the two you will get.
I did try to write a test for it but I was unable to figure out how to do it properly with should.js
This is the code we use in our project in which we work around this problem
class TwigService {

  constructor(twigValues) {
    this._twigValues = twigValues;
  }

  /**
   * @param id The identifier for the template
   * @param html The twig template to parse
   * @param values Values that are used in the twig template
   * @return string
   */
  render(id, html, values) {
    var twigTemplate = Twig.twig({ ref: id });
    if (twigTemplate === null) {
      twigTemplate = Twig.twig({
        id: id,
        data: html,
        autoescape: true,
        rethrow: true
      });
    }

    values = merge.recursive(true, values, this._twigValues);
    values.date = Math.round(Date.now() / 1000);

    // Render returns a String object instead of regular string
    // casting it explicitly to a string fixes this odd behaviour
    try {
      return '' + twigTemplate.render(values);
    } catch(e) {
      return 'An error occured while rendering: ' + e;
    }
  }
}

I tried to merge your pull request, but it fails a test:
  1) Twig.js Functions -> Built-in Functions -> block -> shouldn't escape the content of blocks twice:

      AssertionError: expected 'te&amp;st te&amp;st' to be 'te&st te&st'
      + expected - actual

      +"te&st te&st"
      -"te&amp;st te&amp;st"

Could you please have a look at it again?

@christiaan
A String constructor is used when the contents should be marked as valid Twig markup. It's how we detect if the contents were escaped already. If you convert a String object to a string in the render() method, it impacts the way inheritance works so you'll see double escaping. It's what @plepe mentioned above.
If a type of the output is important to you, you can use template.render().toString() to get a string.

I've looked at what our real problem was. When you pass a String to jQuery's .html() method it behaves differently then when it is passed a normal string.
It has cost us a couple of hours looking with 2 people to figure out what was going on. Especially since this behavior is not documented anywhere.
I'll see if I can get the tests running so I can come up with a different solution.


feat(icon): add pulumi icon

Changes proposed:

[X] Add

More info at pulumi.com
Also changed the order of the closest objects, they were not alphabetical.
@robertohuertasm Can you also check my other PRs please? I've made quite a lot last month and yet none of them has been reviewed 😢 Some of them are meant to close some of the other PRs (which have been stuck here for a long time), and some of the old PRs are already closed, thanks to devs' understanding.

@PAXANDDOS I optimized the icon a little bit. Note that this project is under low maintenance mode these days and most of the icons PR must be reviewed manually. Most of the time, they're ok, but the icons are usually not optimized so it requires some time for us to review.
I'm planning on doing small releases and clean the PR queue, but it all depends on the free time I have which is not that much. Please, be patient as all the PR will eventually be merged or closed.

Got it, thanks ❤
But also,

Most of the time, they're ok, but the icons are usually not optimized so it requires some time for us to review.

How do you optimize icons? I'm always trying to keep them clean while working in AI/Figma, but I guess you do use something else to make code shorter

Yes, we use Illustrator and we export it for web. Normally it is ok if they're 2kb or less. See here the guide in the wiki.
I'd like to provide a non-proprietary guide too, possibly with Inkscape. Hopefully soon! ;D

BTW, maaaany thanks for your contributions!!! ❤ ⭐


Select element cannot have a label

    The label
    <select id="select">
      <option>Select Field</option>
      <option value="1">Option 01</option>
      <option value="2">Option 02</option>
    </select>

Current behavior :
The select element has no label text in examples.
Adding a label text leads to broken style for the select dropdown arrow and the label is not formatted like the other labels.

Expected behavior :
The select element has a label in examples.
The select can be used with or without label.

Hi ! I'm a great fan of your work, I hope my issue is well formatted and comprehensible. Thank you for the good work !

Hi @cramarokoto, can you do the following?

    The label

    <select id="select">
      <option>Select Field</option>
      <option value="1">Option 01</option>
      <option value="2">Option 02</option>
    </select>

Where the first  is using the label styles and has a for="select" attribute to focus the <select> when interacted with.
The second  is for cross-browser styling of the <select>.

That works visually and is HTML5 compliant but the label without descriptive text is missing semantics : it's only there for styling and brings no labelling information.
I also don't know howscreen readers react to this situation.

For example, AChecker (a web accessibility checker) considers that to be an issue as seen here.

Hi @cramarokoto, thanks for your feedback. If you feel it's necessary, you can change the wrapping  to a
 tag.

    The label

-
+

    <select id="select">
      <option>Select Field</option>
      <option value="1">Option 01</option>
      <option value="2">Option 02</option>
    </select>

Thank you for your quick answers.
Unfortunately, p cannot contain block level elements such as div and that makes organising the form complicated. I will switch to fieldset but that stills means I change the semantic of the form for the visual rendering.
<fieldset class="field">

    The label

    <select id="select">
      <option>Select Field</option>
      <option value="1">Option 01</option>
      <option value="2">Option 02</option>
    </select>

</fieldset>

Perhaps a  would be your best bet here:

    The label

-
+
    <select id="select">
      <option>Select Field</option>
      <option value="1">Option 01</option>
      <option value="2">Option 02</option>
    </select>
-
+

I'd argue that a <fieldset> would be best suited to a group of inputs and may have side effects which may disorientate users of screen readers who are not familiar with your suggest pattern.
A <fieldset> will also require a nested <legend> to provide it context within the accessibility tree.
Alternatively using the native <select>, without the HTML workaround for styling in turretcss, might also be a better option: https://css-tricks.com/styling-a-select-like-its-2019/
Depending on your browser support requirements, and appetite for testing across browsers and devices, this would give you more granular control with how you present your HTML.

I agree with you, the fieldset is also a bad idea on second thought. The span seems to match that usage. Thanks !
I'm trying to stick to what's already available in this library since it's really flexible and clean (semantics and accessibility are not polluted by an overuse of wrappers such as div).

I believe that the information you are receiving from ACChecker may be a false positive test result if you have the following:

    The label

    <select id="select">
      <option>Select Field</option>
      <option value="1">Option 01</option>
      <option value="2">Option 02</option>
    </select>

This is because:

<select> is labelled by an associated label above
 wrapping the <select> is included for the pointer events to be provided to the child. When a keyboard user focuses the <select> they provided with the text from the associated  above.

I believe that the tool is evaluating ... as a failure because it doesn't contain a textnode, however, this isn't a concern as the <select> is already laballed.
WCAG 3.3.2: https://www.w3.org/TR/UNDERSTANDING-WCAG20/minimize-error-cues.html

I agree with you, the fieldset is also a bad idea on second thought. The span seems to match that usage. Thanks !
I'm trying to stick to what's already available in this library since it's really flexible and clean (semantics and accessibility are not polluted by an overuse of wrappers such as div).

Good call! I hope that the usage of  resolves this issue.


[turtlebot3_dqn_stage_1-1] process has died [pid 1395, exit code -4,

I have turtlebot3 and im trying to use CONDA and tensorflow. First i use this command:
roslaunch turtlebot3_gazebo turtlebot3_stage_1.launch
and for some reason i cant see the laser, i know i have to change <xacro:arg name="laser_visual" default="false"/>   and put default="true" but it still doesnt work.
Then when i try roslaunch turtlebot3_dqn turtlebot3_dqn_stage_1.launch
I get the next error :
process[turtlebot3_dqn_stage_1-1]: started with pid [1395]
Using TensorFlow backend.
[turtlebot3_dqn_stage_1-1] process has died [pid 1395, exit code -4, cmd /home/laboratorio/catkin_ws/src/turtlebot3_machine_learning/turtlebot3_dqn/nodes/turtlebot3_dqn_stage_1 __name:=turtlebot3_dqn_stage_1 __log:=/home/laboratorio/.ros/log/4baef918-eeba-11e9-91ac-001e4febbb7c/turtlebot3_dqn_stage_1-1.log].
log file: /home/laboratorio/.ros/log/4baef918-eeba-11e9-91ac-001e4febbb7c/turtlebot3_dqn_stage_1-1*.log
all processes on machine have died, roslaunch will exit
shutting down processing monitor...
... shutting down processing monitor complete
done
I have Ubuntu 16.04 xenial
turtlebot3 waffle_pi

@Sebastian5j

Check if the file you modified is for the waffle_pi model (there are three, burger, waffle and waffle_pi). Since you are testing waffle_pi, the file below is what you need to modify.
(turtlebot3/turtlebot3_description/urdf/turtlebot3_waffle_pi.gazebo.xacro)
There are several possible reasons why you are having that issue.

You should run gazebo before running that DQN program (and you didn't)
test below instead of waffle_pi
export TURTLEBOT3_MODEL=burger
The problem is occurring because of Keras related issues. Show us your ~/.bashrc file.

Regards,
Ryan

@rjshim  this is what i have:
in the file turtlebot3_waffle_pi.gazebo.xacro

Gazebo/DarkGrey

0.1
0.1
500000.0
10.0
0.001
0.1
1 0 0
Gazebo/FlatBlack

0.1
0.1
500000.0
10.0
0.001
0.1
1 0 0
Gazebo/FlatBlack

0.1
0.1
1000000.0
100.0
0.001
1.0
Gazebo/FlatBlack

0.1
0.1
1000000.0
100.0
0.001
1.0
Gazebo/FlatBlack

true
$(arg imu_visual)

Gazebo/Grey

cmd_vel
odom
odom
world
true
base_footprint
false
true
true
false
30
wheel_left_joint
wheel_right_joint
0.287
0.066
1
10
na

true
imu_link
imu_link
imu
imu_service
0.0
200

gaussian

0.0
2e-4
0.0000075
0.0000008

0.0
1.7e-2
0.1
0.001

Gazebo/FlatBlack

0 0 0 0 0 0
$(arg laser_visual)
5

24
1
0.0
6.28319

0.120
3.5
0.015

gaussian
0.0
0.01

scan
base_scan

true
$(arg camera_visual)

1.085595

640
480
R8G8B8

0.03
100

true
30.0
camera
camera_rgb_optical_frame
rgb/image_raw
rgb/camera_info
0.07
0.0
0.0
0.0
0.0
0.0

then in my ~/.bashrc:
~/.bashrc: executed by bash(1) for non-login shells.
see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
for examples
If not running interactively, don't do anything
case $- in
i) ;;
*) return;;
esac
don't put duplicate lines or lines starting with space in the history.
See bash(1) for more options
HISTCONTROL=ignoreboth
append to the history file, don't overwrite it
shopt -s histappend
for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
check the window size after each command and, if necessary,
update the values of LINES and COLUMNS.
shopt -s checkwinsize
If set, the pattern "**" used in a pathname expansion context will
match all files and zero or more directories and subdirectories.
#shopt -s globstar
make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi
set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color|*-256color) color_prompt=yes;;
esac
uncomment for a colored prompt, if the terminal has the capability; turned
off by default to not distract the user: the focus in a terminal window
should be on the output of commands, not on the prompt
#force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}[\033[01;32m]\u@\h[\033[00m]:[\033[01;34m]\w[\033[00m]$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$ '
fi
unset color_prompt force_color_prompt
If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a]$PS1"
;;
*)
;;
esac
enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'

fi
colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
Add an "alert" alias for long running commands.  Use like so:
sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '''s/^\s*[0-9]+\s*//;s/[;&|]\s*alert$//''')"'
Alias definitions.
You may want to put all your additions into a separate file like
~/.bash_aliases, instead of adding them here directly.
See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
enable programmable completion features (you don't need to enable
this, if it's already enabled in /etc/bash.bashrc and /etc/profile
sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
alias eb='nano ~/.bashrc'
alias sb='source ~/.bashrc'
alias gs='git status'
alias gp='git pull'
alias cw='cd ~/catkin_ws'
alias cs='cd ~/catkin_ws/src'
alias cm='cd ~/catkin_ws && catkin_make'
source /opt/ros/kinetic/setup.bash
source ~/catkin_ws/devel/setup.bash
export ROS_MASTER_URI=http://<IP_ADDRESS>:11311
export ROS_HOSTNAME=<IP_ADDRESS>
export TURTLEBOT3_MODEL=waffle_pi
#export TURTLEBOT3_MODEL=burger
#<<COMMENT
#>>> conda initialize >>>
#!! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/home/laboratorio/anaconda2/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
eval "$__conda_setup"
else
if [ -f "/home/laboratorio/anaconda2/etc/profile.d/conda.sh" ]; then
. "/home/laboratorio/anaconda2/etc/profile.d/conda.sh"
else
export PATH="/home/laboratorio/anaconda2/bin:$PATH"
fi
fi
unset __conda_setup
#<<< conda initialize <<<
#COMMENT
........................................
And im running this:

roslaunch turtlebot3_gazebo turtlebot3_stage_1.launch
roslaunch turtlebot3_dqn turtlebot3_dqn_stage_1.launch
The second one fails

If i try export TURTLEBOT3_MODEL=burger
the first one fails
I have Keras 2.1.5
and tensorflow 1.2.0

@rjshim  i dont what happend D:  but this is my  turtlebot3_waffle_pi.gazebo.xacro
<xacro:arg name="laser_visual"  default="true"/>
<xacro:arg name="camera_visual" default="true"/>
<xacro:arg name="imu_visual"    default="true"/>
I hope this is what you wanted to see

@Sebastian5j
Use burger model. Before running the first line, run $ conda deactivate. Then, open another terminal window and run the second line. Test it and show me the screenshot of your terminal and gazebo windows.
Regards,
Ryan

@rjshim  I did what you said, this happened:

I also tried to run $conda deactivate in the second windows before $ roslaunch turtlebot3_dqn turtlebot3_dqn_stage_1.launch but the same thing happened

@Sebastian5j
No

$ conda deactivate
$ roslaunch turtlebot3_gazebo turtlebot3_stage_1.launch

Open another window and
$ roslaunch turtlebot3_dqn turtlebot3_dqn_stage_1.launch

Try it and let me know the result

It works now, i found that it was a problem with versions of tensorflow and keras, besides tensorflow wasn't in PYTHONPATH for some reason. Thanks! what you @rjshim  told helped me to find the problem.


License missing from gemspec

Some companies will only use gems with a certain license.
The canonical and easy way to check is via the gemspec,
via e.g.
spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Even for projects that already specify a license, including a license in your gemspec is a good practice, since it is easily
discoverable there without having to check the readme or for a license file. For example, it is the field that rubygems.org uses to display a gem's license.
For example, there is a License Finder gem to help companies ensure all gems they use
meet their licensing needs. This tool depends on license information being available in the gemspec.  This is an important enough
issue that even Bundler now generates gems with a default 'MIT' license.
If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file), github has created a license picker tool.
In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :).
I hope you'll consider specifying a license in your gemspec. If not, please just close the issue and let me know. In either case, I'll follow up. Thanks!
p.s. I've written a blog post about this project

Thanks, awesome! 🌈 🎆

👌