text:
require 'rebellion_g54/action/all'
require 'rebellion_g54/card'
require 'rebellion_g54/choice'
require 'rebellion_g54/claim'
require 'rebellion_g54/decision'
require 'rebellion_g54/player'
require 'rebellion_g54/role'
require 'rebellion_g54/turn'
require 'time'

module RebellionG54; class Game
  GAME_NAME = 'Rebellion G54'.freeze
  MIN_PLAYERS = 2
  MAX_PLAYERS = 6
  ROLES_PER_GAME = 5

  STARTING_INFLUENCE = 2
  STARTING_COINS = 2

  attr_reader :id, :channel_name, :roles
  attr_reader :start_time
  attr_reader :freedom_of_press_enabled
  attr_accessor :synchronous_challenges
  attr_accessor :output_streams

  class << self
    attr_accessor :games_created
  end

  @games_created = 0

  class Token; end

  def initialize(
    channel_name, users, roles,
    freedom_of_press_enabled: true,
    synchronous_challenges: true,
    # for tests
    strict_roles: true, shuffle_players: true, rigged_players: nil
  )
    raise "Need #{ROLES_PER_GAME} roles instead of #{roles.size}" if roles.size != ROLES_PER_GAME
    if strict_roles
      invalid_roles = roles.reject { |r| Role::ALL.has_key?(r) }
      raise "Roles #{invalid_roles} are invalid" unless invalid_roles.empty?
    end

    self.class.games_created += 1
    @id = self.class.games_created

    @channel_name = channel_name

    @start_time = Time.now

    @roles = roles.freeze

    # Settings: Freedom of press can't change mid-game
    @freedom_of_press_enabled = freedom_of_press_enabled

    # Settings: Synchronous challenges can change mid-game
    @synchronous_challenges = synchronous_challenges

    # Various tokens:
    @taxed_role = nil
    @taxing_player = nil

    @treaty_players = [].freeze
    @peace_player = nil

    @bomb_player = nil

    # Hash[Player => Action] (what action placed that token on you?)
    @disappear_players = {}

    @deaths_this_turn = []

    @turns = []

    # List of no-argument functions to call to get more decisions.
    # If it's empty, move on to the next phase.
    @upcoming_decisions = []
    @current_decision = nil

    @communications_available = []
    # Hash[Card => [Player?(Source, nil if deck), Player?(Target, nil if deck)]
    @communications_assignments = {}

    @output_streams = []

    @main_token = Token.new
    @action_token = Token.new

    @players = users.map { |u| Player.new(u, @main_token, @action_token) }
    @players.shuffle! if shuffle_players

    # dead players are no longer in @players, preventing them from taking actions
    @dead_players = []

    @deck = []
    @actions = []
    @actions << Action::Income
    @actions << Action::FreedomOfPress if @freedom_of_press_enabled
    @actions << Action::Coup
    card_id = 1
    @roles.each { |role|
      action = Action.const_get(Role::to_class_name(role))
      action = action.per_game_state.new if action.per_game_state
      @actions << action
      3.times.each {
        @deck << Card.new(card_id, role)
        card_id += 1
      }
    }
    @actions.freeze

    # Hash[Action => Hash[Player(dead_player) => Array[Player(claimant)]]]
    @death_claims = @actions.select { |a| a.timing == :on_death }.map { |a| [a, {}] }.to_h

    @deck.shuffle!

    if rigged_players
      @players.zip(rigged_players).each { |player, rigged|
        cards_to_give = []
        (rigged[:roles] || []).each { |role|
          card = @deck.find { |d| d.role == role }
          if card
            @deck.delete(card)
            cards_to_give << card
          end
        }
        cards_to_give << @deck.shift until cards_to_give.size >= STARTING_INFLUENCE
        player.receive_cards(@main_token, cards_to_give)
        player.give_coins(@action_token, rigged[:coins] || STARTING_COINS)
      }
    else
      @players.each { |player|
        player.receive_cards(@main_token, @deck.shift(STARTING_INFLUENCE))
        player.give_coins(@action_token, STARTING_COINS)
      }
    end

    @players.each { |player|
      raise "#{player} didn't get #{STARTING_INFLUENCE} cards" unless player.influence == STARTING_INFLUENCE
    }

    next_turn
  end

  def output(message)
    @output_streams.each { |o| o.puts(message) }
  end

  #----------------------------------------------
  # Required methods for player management
  #----------------------------------------------

  def size
    @players.size
  end

  def users
    @players.map(&:user)
  end

  def replace_player(replaced, replacing)
    player = find_player(replaced)
    return false unless player
    player.user = replacing
    true
  end

  #----------------------------------------------
  # Please use externally sparingly.
  #----------------------------------------------

  def each_player
    @players.each
  end

  def each_dead_player
    @dead_players.each
  end

  def find_player(user)
    @players.find { |p| p.user == user }
  end

  def find_dead_player(user)
    @dead_players.find { |p| p.user == user }
  end

  #----------------------------------------------
  # Game state getters
  #----------------------------------------------

  def current_user
    current_player.user
  end

  def user_coins(user)
    p = find_player(user)
    p && p.coins
  end

  def user_influence(user)
    p = find_player(user)
    p && p.influence
  end

  def turn_number
    @turns.size
  end

  def decision_description
    @current_decision.description
  end

  def choice_names
    @current_decision.choice_names
  end

  def choice_explanations(user)
    player = find_player(user)
    return [] unless player
    @current_decision.choice_explanations(player)
  end

  def player_tokens
    tokens = Hash.new { |h, k| h[k] = [] }
    tokens[@taxing_player.user] << :tax if @taxing_player
    tokens[@peace_player.user] << :peace if @peace_player
    tokens[@bomb_player.user] << :bomb if @bomb_player
    # Treaty is ineffective when there are only two players, so don't bother.
    @treaty_players.each { |p| tokens[p.user] << :treaty } if self.size > 2
    @disappear_players.each_key { |p| tokens[p.user] << :disappear }
    tokens
  end

  def role_tokens
    return {} unless @taxed_role
    { @taxed_role => [:tax] }
  end

  def winner
    return nil if @players.size > 1
    @players.first.user
  end

  #----------------------------------------------
  # Game state changers
  #----------------------------------------------

  def take_choice(user, choice, *args)
    player = find_player(user)
    return [false, "#{user} is not in the game"] unless player
    @current_decision.take_choice(player, choice, args)
  end

  #----------------------------------------------
  # Action resolvers need these methods.
  #----------------------------------------------

  def give_new_card_from_deck(token, player)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    player.receive_cards(@main_token, [@deck.shift])
  end

  def random_deck_roles(token, n)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    @deck.sample(n).map(&:role)
  end

  #----------------------------------------------
  # Various tokens
  #----------------------------------------------

  def set_tax(token, player, role)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    assert_in_array(role, @roles)
    assert_in_array(player, @players)
    @taxing_player = player
    @taxed_role = role
  end

  def set_treaty(token, player1, player2)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    raise "Can't treaty #{player1} with self" if player1 == player2
    assert_in_array(player1, @players)
    assert_in_array(player2, @players)
    @treaty_players = [player1, player2].freeze
  end

  def set_peace(token, player)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    assert_in_array(player, @players)
    @peace_player = player
  end

  def set_disappear(token, player, action)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    assert_in_array(player, @players)
    @disappear_players[player] = action
  end

  #----------------------------------------------
  # Communications
  #----------------------------------------------

  def communications_add_player(token, player)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    player.each_live_card.each { |c| communications_add_card(player, c) }
  end

  def communications_add_deck(token, count)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    cards = @deck.shift(count)
    cards.each { |c|
      @communications_available << c
      @communications_assignments[c] = [nil, nil]
    }
  end

  #----------------------------------------------
  # Decision enqueuers (for action)
  #----------------------------------------------

  def enqueue_communications_decision(token, player, target = nil)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    @communications_available.sort_by!(&:role)
    @upcoming_decisions.unshift(lambda {
      Decision.single_player(
        current_turn.id, player, "Pick a card for #{target ? target.to_s : 'yourself'}?",
        choices: @communications_available.each_with_index.map { |card, i|
          if (giver = @communications_assignments[card][0]) == player
            text = "Yours"
          elsif giver
            text = "From #{giver}"
          else
            text = "Drawn"
          end
          ["pick#{i + 1}", Choice.new("Pick #{card} (#{text})") { cb_communications_assign(target || player, card) }]
        }.to_h
      )
    })
  end

  def enqueue_communications_redraw_decision(token, player, cost)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    @upcoming_decisions.unshift(lambda {
      cards = @communications_available.map(&:to_s).join(', ')
      Decision.single_player_with_costs(
        current_turn.id, player, 'Pay to draw another card?',
        costs_and_choices: [
          [cost, { 'draw' => Choice.new("Draw another card - you have #{player.coins} coins") {
            # It never dies! It re-enqueues itself!!!
            # May want to stop re-enqueueing if the deck runs out of cards...
            player.take_coins(token, cost, strict: true)
            communications_add_deck(token, 1)
            enqueue_communications_redraw_decision(token, player, cost)
            next_decision
            [true, '']
          }}],
          [0, { 'pass' => Choice.new("Stop and pick from #{cards}") {
            next_decision
            [true, '']
          }}]
        ]
      )
    })
  end

  def enqueue_communications_give_own_card_decision(token, player)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    @upcoming_decisions.unshift(lambda {
      # If nobody gave us any cards, just have a decision that does nothing.
      return AutoDecision.new('No available cards') { next_decision } if @communications_available.empty?

      given = @communications_available.map(&:to_s).join(', ')
      Decision.single_player(
        current_turn.id, player, 'Pick a card to add to the pool',
        choices: player.each_live_card.with_index.map { |card, i|
          ["add#{i + 1}", Choice.new("Add #{card} - others gave #{given}") {
            # Just going to inline this callback
            communications_add_card(player, card)
            next_decision
            [true, '']
          }]
        }.to_h
      )
    })
  end

  def enqueue_communications_give_card_decision(token, giving_player, communicating_player, coin: nil)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    @upcoming_decisions.unshift(lambda {
      choices = [[0, giving_player.each_live_card.with_index.map { |card, i|
        ["give#{i + 1}", Choice.new("Give #{card}") {
          # Just going to inline this callback
          communications_add_card(giving_player, card)
          next_decision
          [true, '']
        }]
      }.to_h]]

      if coin
        coin_choice = Choice.new("Give #{coin} coin#{'s' if coin != 1}") {
          giving_player.take_coins(token, coin, strict: true)
          communicating_player.give_coins(token, coin)
          next_decision
          [true, '']
        }
        choices << [coin, {'pay' => coin_choice}]
      end

      Decision.single_player_with_costs(
        current_turn.id, giving_player, "Pick a card to give to #{communicating_player}",
        costs_and_choices: choices,
      )
    })
  end

  def enqueue_communications_random_resolution(token, active_player)
    @upcoming_decisions.unshift(lambda {
      AutoDecision.new('Randomly distribute cards') {
        sources = @communications_assignments.values.map { |src, tgt| src } - [active_player]
        sources.shuffle!
        @communications_assignments.values.each { |v| v[1] = sources.shift unless v[1] }
        generic_advance_phase
      }
    })
  end

  def enqueue_bomb_decision(token, player, action_class, eligible_players)
    @bomb_player = player
    raise 'Only Game or action resolvers should call this method' if token != @action_token

    @upcoming_decisions.unshift(lambda {
      # For each eligible player, you could pass the bomb on to that player.
      claim_choices = eligible_players.map { |target|
        ["bomb#{target}", Choice.new("Give bomb to #{target}") {
          output("#{player} would like to give the bomb to #{target}!")

          new_claim = Claim.new(player, action_class, :block)

          @upcoming_decisions.unshift(lambda {
            AutoDecision.new('Move bomb') {
              # If claim is still OK, enqueue new bomb decision (this will move the bomb token).
              if new_claim.truthful?
                # Some players may have died from challenges; remove them.
                new_eligible_players = eligible_players.select { |p| p != target && p.alive? }
                enqueue_bomb_decision(token, target, action_class, new_eligible_players)
              end
              next_decision
            }
          })

          enqueue_challenge_decision_and_pay_tax(new_claim)
          next_decision
          [true, '']
        }]
      }.to_h

      # You could defuse the bomb.
      claim_choices['defuse'] = Choice.new('Defuse bomb') {
        output("#{player} would like to defuse the bomb!")

        new_claim = Claim.new(player, action_class, :block)

        @upcoming_decisions.unshift(lambda {
          AutoDecision.new('Defuse bomb') {
            # If claim is still OK, remove bomb token.
            @bomb_player = nil if new_claim.truthful?
            next_decision
          }
        })

        enqueue_challenge_decision_and_pay_tax(new_claim)
        next_decision
        [true, '']
      }

      # Or you could take the hit.
      pass = Choice.new('Do not move or defuse bomb') {
        next_decision
        [true, '']
      }

      cost = tax_for(player, action_class)
      Decision.single_player_with_costs(
        current_turn.id, player, 'You are being bombed',
        costs_and_choices: [[cost, claim_choices], [0, {'pass' => pass}]],
      )
    })
  end

  def enqueue_bomb_detonation(token, action_class)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    @upcoming_decisions.unshift(lambda {
      AutoDecision.new('Bomb detonates') {
        enqueue_lose_influence_decision(token, @bomb_player, action_class) if @bomb_player
        @bomb_player = nil
        generic_advance_phase
      }
    })
  end

  def enqueue_lose_influence_decision(token, player, action_class, disappear_action: nil, extort_cost: nil, extort_player: nil)
    raise 'Only Game or action resolvers should call this method' if token != @action_token
    @upcoming_decisions.unshift(lambda {
      choices = player.each_live_card.with_index.map { |card, i|
        [0, { "lose#{i + 1}" => Choice.new("Lose #{card}") { cb_lose_card(player, card) }}]
      }
      if disappear_action
        cost = tax_for(player, disappear_action.class)
        text = "Block #{disappear_action.class.flavor_name}"
        text << " ( tax of #{cost} coins)" if cost > 0
        choices << [cost, {
          "#{disappear_action.class.slug}" => Choice.new(text) {
            cb_block_disappear(player, disappear_action, end_turn: true)
          }
        }]
      end
      choices << [extort_cost, {
        'pay' => Choice.new("Pay #{extort_cost} to #{extort_player}") { cb_extorted(player, extort_player, extort_cost) }
      }] if extort_cost && extort_player
      @actions.select { |a|
        a.timing == :on_lose_influence && (action_class != Action::Coup || a.responds_to_coup?)
      }.each { |action|
        cost = tax_for(player, action)
        player.each_live_card.with_index { |card, i|
          text = "Claim #{card} is #{Role.to_s(action.required_role)}#{" (tax of #{cost} coin)" if cost > 0}"
          choices << [cost, { "#{action.slug}#{i + 1}" => Choice.new(text) { cb_react_to_lose_card(player, card, action) }}]
        }
      }
      Decision.single_player_with_costs(
        current_turn.id, player, 'Lose influence',
        costs_and_choices: choices
      )
    })
  end

  private

  def current_turn
    @turns.last
  end

  def current_player
    current_turn.active_player
  end

  def inactive_players
    @players - [current_player]
  end

  def player_loses_card(player, card)
    player.flip_card(@main_token, card)
    output("#{player} loses influence over a #{card} and now has #{player.influence} influence")
    check_whether_player_died(player)
  end

  def check_whether_player_died(player)
    return if player.influence > 0
    if @taxing_player == player
      @taxing_player = nil
      @taxed_role = nil
    end
    player.die!(@main_token)
    @players.delete(player)
    @deaths_this_turn << player
    @dead_players << player
    @output_streams.each { |os| os.player_died(player.user) }
  end

  # Removes card from player, switches with new from deck
  def replace_card_with_new(player, card)
    @deck << card
    @deck.shuffle!
    new_card = @deck.shift
    return if new_card == card
    # This will raise if player didn't have the old card
    player.replace_cards(@main_token, [card], [new_card])
    @output_streams.each { |os| os.new_cards(player.user) }
  end

  def communications_add_card(player, card)
    @communications_available << card
    @communications_assignments[card] = [player, nil]
  end

  def communications_commit
    return if @communications_assignments.empty?
    # This player_deltas is here for sanity checking.
    # Also Player#receive_cards will balk if I add cards without removing.
    # Hash[player => [cards_to_lose, cards_to_gain]]
    player_deltas = Hash.new { |h, k| h[k] = [[], []] }
    @communications_assignments.each { |card, (source, destination)|
      # Card is going to/from the same player, just skip it.
      next if source && source == destination
      player_deltas[source][0] << card if source
      if destination
        player_deltas[destination][1] << card
      else
        @deck << card
      end
    }

    # Player#replace_cards will do the sanity check
    player_deltas.each { |player, (lose, gain)|
      player.replace_cards(@main_token, lose, gain)
      @output_streams.each { |os| os.new_cards(player.user) }
    }

    @deck.shuffle!
    @communications_available.clear
    @communications_assignments.clear
  end

  #----------------------------------------------
  # Callbacks
  #----------------------------------------------

  def cb_action(player, action_class, args)
    parsed_args = []
    action_class.arguments.zip(args).each { |expected_arg, arg|
      return [false, "Missing an argument: #{expected_arg}"] unless arg

      arg_type = expected_arg[:type]
      opts = expected_arg

      case arg_type
      when :player
        target = find_player(arg)
        return [false, "No such player #{arg}"] unless target
        return [false, "Can't target yourself with #{action_class}"] if target == player && !opts[:self]
        unless opts[:friendly]
          # You can't target your treaty partner with anything unfriendly, not even Coup
          return [false, "Can't target #{target} because of Treaty"] if self.size > 2 && @treaty_players.include?(player) && @treaty_players.include?(target)
          # You can't target a peaced player with anything unfriendly except for Coup
          return [false, "Can only target #{target} with Coup because of Peace Keeping"] if @peace_player == target && action_class != Action::Coup
        end
        @players.each { |p|
          return [false, "#{target} is not the richest player (#{p} is richer)"] if p.coins > target.coins
        } if opts[:richest]
        @players.each { |p|
          return [false, "#{target} is not the poorest player (#{p} is poorer)"] if p.coins < target.coins
        } if opts[:poorest]
        return [false, "Can't target the same player #{target} twice"] if parsed_args.include?(target)
        parsed_args << target
      when :role
        # No to_sym (Well, I'm on Ruby 2.2 so I can garbage-collect symbols, but I don't want to rely on it?)
        target = @roles.find { |r| r.to_s == arg.downcase }
        return [false, "No such role #{arg}"] unless target
        parsed_args << target
      else raise "Unexpected argument type #{expected_arg}"
      end
    }

    if action_class.targets_all
      targets = inactive_players
      targets.delete(@peace_player) if @peace_player
      targets -= @treaty_players if self.size > 2 && @treaty_players.include?(player)
      parsed_args.concat(targets)
    end

    action = action_class.new(*parsed_args)

    # Conditional costs might cause the player to not be able to take an action.
    # (Fixed costs should have been rendered invalid already)
    if player.coins < action.cost + tax_for(player, action_class)
      costs = format_costs(player, action_class) + action.conditional_costs
      return [false, "Need #{costs.join(' and ')}"]
    end

    current_turn.action = action
    output("#{player} would like to use #{action}!")

    if action_class.required_role && action_class.action_requires_role
      enqueue_challenge_decision_and_pay_tax(current_turn.action_claim)
      next_decision
    else
      join_phase
    end

    [true, '']
  end

  def cb_challenge(claim, challenger)
    claim.challenger = challenger
    if claim.type == :on_lose_influence
      output("#{challenger} challenges #{claim.claimant} to show that the set-aside card is #{Role.to_s(claim.role)}!")
      return cb_show_for_challenge(claim, claim.card, on_lose_influence: true)
    end
    enqueue_challenge_response_decision(claim, challenger)
    # No announcement needed since the decision will change.
    next_decision
    [true, '']
  end

  def cb_pass_challenge(claim, challenger)
    output("#{challenger} chooses not to challenge.")
    @current_decision.clear_player(challenger)
    # If no living players have a decision left to make, advance.
    generic_advance_phase unless @current_decision.valid_players.any?(&:alive?)
    [true, '']
  end

  def cb_join(turn, joiner)
    claim = turn.join(joiner)
    if claim.is_a?(Claim)
      output("#{joiner} would like to join in #{turn.action.class.flavor_name}!")
      enqueue_challenge_decision_and_pay_tax(claim, delayed: turn.action.class.join_challenges_delayed)
      next_decision
    else
      output("#{joiner} joins in #{turn.action.class.flavor_name}!")
      turn.action.player_joined(joiner)
      generic_advance_phase
    end
    [true, '']
  end

  def cb_pass_join(turn, joiner)
    output("#{joiner} chooses not to join.")
    # Only one player should be up for joining at a time, so we can advance.
    generic_advance_phase
    [true, '']
  end

  def cb_block(turn, blocker)
    claim = turn.block(blocker)
    enqueue_challenge_decision_and_pay_tax(claim)
    output("#{blocker} would like to block #{turn.action.class.flavor_name}!")
    next_decision
    [true, '']
  end

  def cb_pass_block(turn, blocker)
    output("#{blocker} chooses not to block.")
    # Only one player should be up for blocking at a time, so we can advance.
    generic_advance_phase
    [true, '']
  end

  def cb_show_for_challenge(claim, card, on_lose_influence: false)
    if card.role == claim.role
      if on_lose_influence
        output("#{claim.claimant} was telling the truth! #{claim.claimant} reveals the [#{card}] that was set aside.")
        claim.claimant.flip_side_card(@main_token, card)
      else
        output("#{claim.claimant} was telling the truth! #{claim.claimant} shuffles [#{card}] into the deck.")
        replace_card_with_new(claim.claimant, card)
      end
      claim.truthful = true
      enqueue_lose_influence_decision(@action_token, claim.challenger, nil)
      next_decision
    else
      output("#{claim.claimant} was lying! It was a #{card}, not a #{Role.to_s(claim.role)}! #{claim.claimant} can't #{claim.effect} this round.")
      claim.action_class.found_lying(@action_token, claim.claimant, claim.challenger)
      claim.truthful = false
      if on_lose_influence
        claim.claimant.flip_side_card(@main_token, card)
        enqueue_lose_influence_decision(@action_token, claim.claimant, nil)
        next_decision
      else
        player_loses_card(claim.claimant, card)
        generic_advance_phase
      end
    end
    [true, '']
  end

  def cb_lose_challenge_and_react(claim, card, action_class)
    output("#{claim.claimant} was lying! #{claim.claimant} can't #{claim.effect} this round.")
    claim.action_class.found_lying(@action_token, claim.claimant, claim.challenger)
    claim.truthful = false
    cb_react_to_lose_card(claim.claimant, card, action_class)
  end

  def cb_claim_on_death(player, action_class, dead_player)
    output("#{player} would like to use #{action_class.new(dead_player)}!")
    new_claim = Claim.new(player, action_class, :on_death)
    @death_claims[action_class][dead_player] << new_claim
    enqueue_challenge_decision_and_pay_tax(new_claim)
    next_decision
    [true, '']
  end

  def cb_communications_assign(target, card)
    @communications_available.delete(card)
    @communications_assignments[card][1] = target
    generic_advance_phase
    [true, '']
  end

  def cb_lose_card(player, card)
    player_loses_card(player, card)
    generic_advance_phase
    [true, '']
  end

  def cb_block_disappear(player, action, start_turn: false, end_turn: false)
    output("#{player} would like to block #{action.class.flavor_name}!")
    new_claim = Claim.new(player, action.class, :block)
    enqueue_challenge_decision_and_pay_tax(new_claim)
    # This one pushes, so putting it here is right.
    enqueue_disappear_resolution(new_claim, relose_if_wrong: end_turn)
    # Re-enqueue my action decision.
    @upcoming_decisions.push(lambda { decision_for_new_turn(player) }) if start_turn
    next_decision
    [true, '']
  end

  def cb_extorted(extorted_player, extorting_player, extort_cost)
    output("#{extorted_player} gives in to extortion and pays #{extort_cost} coins to #{extorting_player}.")
    extorted_player.take_coins(@action_token, extort_cost, strict: true)
    # Remember, extorting player also gets a refund on the action cost.
    extorting_player.give_coins(@action_token, extort_cost + current_turn.action.class.cost)
    generic_advance_phase
    [true, '']
  end

  def cb_react_to_lose_card(player, card, action_class)
    output("#{player} sets aside a card face-down and would like to use #{action_class.new}!")
    player.set_aside(@main_token, card, action_class.required_role)
    new_claim = Claim.new(player, action_class, :on_lose_influence, card: card)
    enqueue_reaction_resolution(new_claim)
    enqueue_challenge_decision_and_pay_tax(new_claim)
    next_decision
    [true, '']
  end

  #----------------------------------------------
  # Decision enqueuers
  #----------------------------------------------

  # OK fine, this one just returns it, but close enough.
  def decision_for_new_turn(player)
    choices = @actions.select { |a| a.timing == :main_action }.map { |action|
      choice = Choice.new(action.name_and_effect, action.arguments) { |args| cb_action(player, action, args) }
      last_player = @turns.size >= 2 ? @turns[-2].active_player : nil

      if player.coins >= 10 && action != Action::Coup
        choice.unavailable!('You must Coup when you have at least 10 coins.')
      elsif player.coins < action.cost + tax_for(player, action)
        choice.unavailable!("Need #{format_costs(player, action).join(' and ')}")
      elsif last_player == player && action.another_turn?
        choice.unavailable!('Would cause three turns in a row')
      end

      [action.slug, choice]
    }.to_h

    # If player has a disappear token, add the block option.
    if (disappear_action = @disappear_players[player])
      action_class = disappear_action.class
      tax = tax_for(player, action_class)
      name = action_class.flavor_name
      choice = Choice.new("Block #{name}#{" (tax of #{tax} coin)" if tax > 0}") {
        cb_block_disappear(player, disappear_action, start_turn: true)
      }
      choice.unavailable!("Need #{format_costs(player, action_class)}") if player.coins < tax
      choices['block'] = choice
    end

    Decision.single_player(
      current_turn.id, player, "#{player}'s turn to choose an action",
      choices: choices,
    )
  end

  def enqueue_multi_decision(turn, candidates, verb, yes_cb, no_cb, requires_role: true, base_cost: 0)
    return false if candidates.empty?

    candidates.each { |candidate|
      @upcoming_decisions.push(lambda {
        reqs = []
        tax = tax_for(candidate, turn.action.class)
        cost = tax
        if requires_role
          reqs << "also claiming #{Role.to_s(turn.action.class.required_role)}"
          reqs << "paying tax of #{tax} coin" if tax > 0
        end
        if base_cost > 0
          reqs << "paying #{base_cost} coins"
          cost += base_cost
        end

        Decision.single_player_with_costs(
          current_turn.id, candidate, "#{verb.capitalize} #{turn.active_player}'s #{turn.action.class.flavor_name} by #{reqs.join(' and ')}?",
          costs_and_choices: [
            [cost, { verb => Choice.new("#{verb.capitalize}!!!") { yes_cb.call(candidate) }}],
            [0, { 'pass' => Choice.new("Do not #{verb}") { no_cb.call(candidate) }}],
          ]
        )
      })
    }

    true
  end

  def enqueue_join_decision(turn)
    # The target shouldn't be joining (Protesters is example).
    candidates = inactive_players - turn.action.original_targets

    enqueue_multi_decision(
      turn, candidates, 'join',
      lambda { |candidate| cb_join(turn, candidate) },
      lambda { |candidate| cb_pass_join(turn, candidate) },
      requires_role: turn.action.class.join_requires_role,
      base_cost: turn.action.class.join_cost
    )
  end

  def enqueue_block_decision(turn)
    enqueue_multi_decision(
      turn, turn.action.potential_blockers - [turn.active_player], 'block',
      lambda { |candidate| cb_block(turn, candidate) },
      lambda { |candidate| cb_pass_block(turn, candidate) },
      requires_role: true,
      base_cost: 0
    )
  end

  def enqueue_challenge_decision_and_pay_tax(claim, delayed: false)
    # Since taxes always happen in conjunction with making a challengeable claim.
    pay_tax(claim.claimant, claim.action_class)

    text = claim.card ? 'the face-down card being' : 'having influence over'
    description = "Challenge #{claim.claimant} on #{text} #{Role.to_s(claim.role)}?"
    challengers = @players - [claim.claimant]

    if @synchronous_challenges
      decisions = challengers.map { |challenger| lambda {
        choices = {
          'challenge' => Choice.new('Challenge!!!') { cb_challenge(claim, challenger) },
          'pass' => Choice.new('Do not challenge') { cb_pass_challenge(claim, challenger) },
        }
        Decision.single_player(
          current_turn.id, challenger, description,
          # If someone's already challenged it, do nothing.
          choices: claim.challenger ? {} : choices
        )
      }}
      if delayed
        @upcoming_decisions.concat(decisions)
      else
        @upcoming_decisions.unshift(*decisions)
      end
    else
      decision = lambda {
        Decision.new(
          current_turn.id, description,
          choices: challengers.map { |challenger|
            [challenger, {
              'challenge' => Choice.new('Challenge!!!') { cb_challenge(claim, challenger) },
              'pass' => Choice.new('Do not challenge') { cb_pass_challenge(claim, challenger) },
            }]
          }.to_h
        )
      }
      if delayed
        @upcoming_decisions.push(decision)
      else
        @upcoming_decisions.unshift(decision)
      end
    end
  end

  def enqueue_challenge_response_decision(claim, challenger)
    player = claim.claimant
    @upcoming_decisions.unshift(lambda {
      choices = player.each_live_card.with_index.map { |card, i|
        [0, { "show#{i + 1}" => Choice.new("Show #{card}") { cb_show_for_challenge(claim, card) }}]
      }
      @actions.select { |a| a.timing == :on_lose_influence }.each { |action|
        cost = tax_for(player, action)
        player.each_live_card.with_index { |card, i|
          text = "Claim #{card} is #{Role.to_s(action.required_role)}#{" (tax of #{cost} coin)" if cost > 0}"
          choices << [cost, { "#{action.slug}#{i + 1}" => Choice.new(text) { cb_lose_challenge_and_react(claim, card, action) }}]
        }
      }
      Decision.single_player_with_costs(
        current_turn.id, player, "#{challenger} challenges #{player} on having influence over #{Role.to_s(claim.role)}",
        costs_and_choices: choices
      )
    })
  end

  def enqueue_on_death_decisions(dead_player)
    death_actions = @actions.select { |a| a.timing == :on_death }
    return false if death_actions.empty?
    death_actions.each { |action_class|
      @death_claims[action_class][dead_player] = []

      # Enqueue resolution "decision" to happen after everyone has made claims/challenges
      @upcoming_decisions.unshift(lambda {
        successful_claimers = @death_claims[action_class][dead_player].select(&:truthful?).map(&:claimant)
        AutoDecision.new("#{action_class} for #{dead_player}'s death") {
          unless successful_claimers.empty?
            action = action_class.new(dead_player)
            verb = successful_claimers.size == 1 ? 'uses' : 'use'
            output("#{successful_claimers.join(', ')} #{verb} #{action_class.flavor_name}: #{action.effect}")
            action.resolve(self, @action_token, dead_player, successful_claimers, [dead_player])
          end
          generic_advance_phase
        }
      })
    }

    # Enqueue decision for each player * each on_death role
    # Reverse so that current player goes first
    # (we are doing unshift, not append, because these can chain)
    @players.reverse_each { |player|
      # There's only one on_death action right now.
      # If there ever were multiples, this code lets p1 decide whether to claim one or both, then p2, etc.
      # If that assumption ever turns out to be wrong, then modify this code.
      death_actions.each { |action|
        @upcoming_decisions.unshift(lambda {
          cost = tax_for(player, action)
          text = "Claim influence over #{Role.to_s(action.required_role)}#{" (tax of #{cost} coin)" if cost > 0}"
          Decision.single_player_with_costs(
            current_turn.id, player, "#{dead_player} died. #{text}?",
            costs_and_choices: [
              [cost, { "#{action.slug}" => Choice.new('Claim!!!') { cb_claim_on_death(player, action, dead_player) } }],
              [0, { 'pass' => Choice.new('Do not claim') { generic_advance_phase; [true, ''] } }],
            ]
          )
        })
      }
    }

    true
  end

  def enqueue_reaction_resolution(claim)
    @upcoming_decisions.unshift(lambda {
      AutoDecision.new("#{claim.action_class} for #{claim.claimant}") {
        if claim.truthful?
          action = claim.action_class.new
          output("#{claim.claimant} uses #{claim.action_class.flavor_name}: #{action.effect}!")
          action.resolve(self, @action_token, claim.claimant, [], [])
        end
        check_whether_player_died(claim.claimant)
        generic_advance_phase
      }
    })
  end

  def enqueue_disappear_resolution(claim, relose_if_wrong: false)
    @upcoming_decisions.push(lambda {
      AutoDecision.new("#{claim.action_class} against #{claim.claimant}") {
        if claim.truthful?
          output("#{claim.claimant} blocks #{claim.action_class.flavor_name} with #{Role.to_s(claim.action_class.required_role)}!")
          @disappear_players.delete(claim.claimant)
          generic_advance_phase
        else
          enqueue_lose_influence_decision(@action_token, claim.claimant, claim.action_class) if relose_if_wrong
          next_decision
        end
      }
    })
  end

  #----------------------------------------------
  # Game phase changes
  #----------------------------------------------

  def next_decision
    upcoming = @upcoming_decisions.shift
    @current_decision = upcoming.call

    if @current_decision.is_a?(AutoDecision)
      # It is assumed the decision will advance the state as necessary.
      @current_decision.call
      return
    end

    raise "#{@current_decision} not a Decision" unless @current_decision.is_a?(Decision)

    if @current_decision.empty? || !@current_decision.valid_players.any?(&:alive?)
      # Can happen when a lose influence decision targets a player who died to a challenge.
      # We can't auto-complete it because there's no callback, so advance.
      generic_advance_phase
    elsif @current_decision.can_auto_complete?
      # If we can auto-complete a decision, do it.

      unavailable = @current_decision.unavailable
      # Explain any unavailable decisions
      unless unavailable.empty?
        explanations = unavailable.each.map { |player, choices| "#{player} can't #{choices.join(', ')}" }.join(' - ')
        output("#{@current_decision.description} - #{explanations}")
      end
      @current_decision.auto_complete
      # Don't call advance_phase because the callback will do it =D
    end
  end

  def generic_advance_phase
    if @upcoming_decisions.empty?
      case current_turn.state
      when :action; join_phase
      when :join; block_phase
      when :block; resolve_phase
      when :resolve; on_death_or_next_turn(:resolve)
      when :on_death; on_death_or_next_turn(:on_death)
      when :finished; raise "Can't advance #{current_turn.id}; turn ended"
      end
    else
      next_decision
    end
  end

  def join_phase
    current_turn.state = :join
    action_class = current_turn.action.class
    if current_turn.should_resolve? && action_class.joinable? && enqueue_join_decision(current_turn)
      next_decision
    else
      block_phase
    end
  end

  def block_phase
    current_turn.state = :block
    action_class = current_turn.action.class
    if current_turn.should_resolve? && action_class.blockable? && enqueue_block_decision(current_turn)
      next_decision
    else
      resolve_phase
    end
  end

  def resolve_phase
    current_turn.state = :resolve
    if current_turn.should_resolve?
      current_player.take_coins(@action_token, current_turn.action.cost, strict: true)

      targets = current_turn.action.original_targets
      successful_joins = current_turn.successful_joins
      successful_blocks = current_turn.successful_blocks
      unblocked = targets - successful_blocks

      successful_joins.each { |joiner|
        joiner.take_coins(@action_token, current_turn.action.class.join_cost, strict: true)
      }

      current_turn.action.prepare(self, @action_token)

      str = "#{current_player} uses #{current_turn.action.class.flavor_name}"
      str << " (joined by #{successful_joins.map(&:to_s).join(', ')})" unless successful_joins.empty?
      str << " (blocked by #{successful_blocks.map(&:to_s).join(', ')})" unless successful_blocks.empty?
      str << ": #{current_turn.action.effect(target_players: unblocked)}!"
      output(str)

      current_turn.action.resolve(self, @action_token, current_player, successful_joins, unblocked)

      # Some actions listen for other actions, notify them now (Income -> World Bank)
      @actions.each { |a| a.action_performed(current_turn.action.class) }
    end

    if (disappear_action = @disappear_players[current_player])
      enqueue_lose_influence_decision(@action_token, current_player, disappear_action.class, disappear_action: disappear_action)
    end

    if @upcoming_decisions.empty?
      on_death_or_next_turn(:resolve)
    else
      next_decision
    end
  end

  def on_death_or_next_turn(previous_state)
    current_turn.state = :on_death unless previous_state == :on_death
    if !@deaths_this_turn.empty? && enqueue_on_death_decisions(@deaths_this_turn.shift)
      next_decision
    else
      next_turn
    end
  end

  def next_turn
    current_turn.state = :finished unless current_turn.nil?

    # It's possible that communication actions could enqueue an auto-completed decision for this.
    # Seems a bit clumsy to ask them to have to do that, so let's not.
    communications_commit

    # If the active player was killed, do not rotate.
    # Rotating would skip the player after the active player!
    if current_turn
      another_turn = current_turn.action.class.another_turn? && current_turn.should_resolve?
      active_player_killed = !current_turn.active_player.alive?
      @players.rotate! unless active_player_killed || another_turn
    else
      @players.rotate!
    end

    player = @players.first
    @turns << Turn.new(@turns.size + 1, player)

    @current_decision = decision_for_new_turn(player)
  end

  #----------------------------------------------
  # Misc stuff
  #----------------------------------------------

  def assert_in_array(player, array)
    raise "#{player} not in game #{@channel_name}" unless array.include?(player)
  end

  def tax_for(player, action)
    return 0 unless action.required_role
    return 0 if !@taxing_player || player == @taxing_player || !@taxing_player.alive?
    action.required_role == @taxed_role ? 1 : 0
  end

  def pay_tax(player, action_class)
    tax = tax_for(player, action_class)
    return if tax == 0
    player.take_coins(@action_token, tax, strict: true)
    output("#{player} pays the tax of #{tax} coin to #{@taxing_player}.")
    @taxing_player.give_coins(@action_token, tax)
  end

  def format_costs(player, action)
    tax = tax_for(player, action)
    [
      ("#{action.cost} coins for #{action.flavor_name}" if action.cost > 1),
      ("1 coin for #{action.flavor_name}" if action.cost == 1),
      ("#{tax} coins for tax" if tax > 1),
      ("1 coin for tax" if tax == 1),
    ].compact
  end
end; end


text:
<title>TimeEpochToYMDHMS</title>
<link rel=stylesheet href=../../../css/doc.css type=text/css>

Home|
general
|	src.lib	|	time	|
TimeEpochToYMDHMS
Index

TimeEpochToYMDHMS

Syntax

	void TimeEpochToYMDHMS(double tme,int *yr,int *mo,int *dy,int *hr,int *mn, double *sc);

Header

general/rtime.h

Library

	rtime

Description

The TimeEpochToYMDHMS function converts a time expressed as seconds from 0:00UT January 1, 1970, into a year, month, day, hour,minute and second.

The time to convert is given by the argument tme. The converted time and date are stored at the locations pointed to by the arguments yr, mo, dy, hr, mt, and sc.

Returns

	None

Errors

	None

Example

Source Code: TimeEpochToYMDHMS.c

/* TimeEpochToYMDHMS.c
   ===================
   Author: R.J.Barnes
*/

#include <stdio.h>
#include <stdlib.h>
#include "rtime.h"

int main(int argc,char *argv[]) {

  int yr,mo,dy,hr,mt;
  double sc;

  double tval=1030701600;

  TimeEpochToYMDHMS(tval,&yr,&mo,&dy,&hr,&mt,&sc);

  fprintf(stdout,"TimeEpochToYMDHMS'n");
  fprintf(stdout,"Tval: %d'n",(int) tval);
  fprintf(stdout,"Time: %.4d-%.2d-%.2d %.2d:%.2d:%.2d'n",
          yr,mo,dy,hr,mt, (int)sc);

  return 0;
}

    © Johns Hopkins Applied Physics Laboratory 2010

redpajama_set_name: RedPajamaGithub


text: moduleSearchIndex = [{"l":"org.freedesktop.dbus.transport.jre"}];updateSearchResults();


text:
package unnamed;

import java.io.File;

import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Configuration;
import unnamed.block.BlockDropsStore;
import unnamed.config.ConfigStorage;
import unnamed.config.properties.CommandConfig;
import unnamed.config.properties.ConfigProcessing;
import unnamed.handler.DebugScreenHandler;
import unnamed.network.IdSyncManager;
import unnamed.network.event.NetworkEventManager;
import unnamed.network.rpc.RpcCallDispatcher;
import unnamed.network.rpc.targets.EntityRpcTarget;
import unnamed.network.rpc.targets.SyncRpcTarget;
import unnamed.network.rpc.targets.TileEntityRpcTarget;
import unnamed.proxy.IUnnamedProxy;
import unnamed.source.ClassSourceCollector;
import unnamed.source.CommandSource;
import unnamed.sync.SyncChannelHolder;
import unnamed.utils.bitmap.IRpcDirectionBitMap;
import unnamed.utils.bitmap.IRpcIntBitMap;

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;

@Mod(modid = Unnamed.MODID, name = Unnamed.MODID, version = "$LIB-VERSION$", guiFactory = "unnamed.GuiFactory")
public class Unnamed {

    public static final String MODID = "Unnamed";

    @Instance(MODID)
    public static Unnamed instance;

    @SidedProxy(clientSide = "unnamed.proxy.UnnamedClientProxy", serverSide = "unnamed.proxy.UnnamedServerProxy")
    public static IUnnamedProxy proxy;

    private ClassSourceCollector collector;

    public ClassSourceCollector getCollector() {
        return collector;
    }

    @EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        SyncChannelHolder.ensureLoaded();

        NetworkEventManager.INSTANCE.startRegistration();

        RpcCallDispatcher.INSTANCE.startRegistration()
                .registerInterface(IRpcDirectionBitMap.class)
                .registerInterface(IRpcIntBitMap.class)
                .registerTargetWrapper(EntityRpcTarget.class)
                .registerTargetWrapper(TileEntityRpcTarget.class)
                .registerTargetWrapper(SyncRpcTarget.SyncEntityRpcTarget.class)
                .registerTargetWrapper(SyncRpcTarget.SyncTileEntityRpcTarget.class);

        final File configFile = event.getSuggestedConfigurationFile();
        Configuration config = new Configuration(configFile);
        ConfigProcessing.processAnnotations(MODID, config, LibConfig.class);
        if (config.hasChanged()) config.save();

        MinecraftForge.EVENT_BUS.register(DebugScreenHandler.instance);

        MinecraftForge.EVENT_BUS.register(BlockDropsStore.instance.createForgeListener());

        FMLCommonHandler.instance().bus().register(BlockDropsStore.instance.createFmlListener());

        FMLCommonHandler.instance().bus().register(ConfigStorage.instance);

        collector = new ClassSourceCollector(event.getAsmData());

        proxy.preInit();
    }

    @EventHandler
    public void init(FMLInitializationEvent event) {
        proxy.init();
    }

    @EventHandler
    public void postInit(FMLPostInitializationEvent event) {
        // Integration stuff goes here
        proxy.postInit();

        NetworkEventManager.INSTANCE.finalizeRegistration();
        RpcCallDispatcher.INSTANCE.finishRegistration();

        // must be after all builders are done
        IdSyncManager.INSTANCE.finishLoading();
    }

    @EventHandler
    public void serverStart(FMLServerStartingEvent event) {
        event.registerServerCommand(new CommandConfig("un_config_s", true));
        event.registerServerCommand(new CommandSource("un_source_s", true, collector));
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="3dp" />
    <solid android:color="@color/actionbar_blue" />
</shape>


text:
'use strict';

describe('myApp.activity module', function() {

  beforeEach(module('myApp.activity'));

  describe('activity controller', function(){

    it('should ....', inject(function($controller) {
      //spec body
      var ctrl = $controller('ActivityController');
      expect(ctrl).toBeDefined();
    }));

  });
});


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
null

#### Original name
Glyphis heterostycha Hepp

### Remarks
null


text:
struct rgb {
  constexpr rgb() : r(0), g(0), b(0) {}
  constexpr rgb(uint8_t r_, uint8_t g_, uint8_t b_) : r(r_), g(g_), b(b_) {}
  constexpr rgb(uint32_t hex) : r((hex >> 16) & 0xFF), g((hex >> 8) & 0xFF), b(hex & 0xFF) {}
  constexpr rgb(COLORREF hex)
      : r((uint32_t(hex) >> 16) & 0xFF), g((uint32_t(hex) >> 8) & 0xFF), b(uint32_t(hex) & 0xFF) {}
  uint8_t r;
  uint8_t g;
  uint8_t b;
};

// swap to LE
inline COLORREF calcLuminance(UINT32 cr) {
  cr = bela::fromle(cr);
  int r = (cr & 0xff0000) >> 16;
  int g = (cr & 0xff00) >> 8;
  int b = (cr & 0xff);
  return RGB(r, g, b);
}

class VisualStudioSeacher {
public:
  using container_t = std::vector<clangbuilder::VSInstance>;
  VisualStudioSeacher() = default;
  VisualStudioSeacher(const VisualStudioSeacher &) = delete;
  VisualStudioSeacher &operator=(const VisualStudioSeacher &) = delete;
  bool Execute(std::wstring_view root, std::wstring_view ewdkroot);
  const container_t &Instances() const { return instances; }
  int Index() const {
    if (instances.empty()) {
      return 0;
    }
    return static_cast<int>(instances.size() - 1);
  }
  size_t Size() const { return instances.size(); }
  const wchar_t *Version(int i) const {
    if (i < 0 || i >= instances.size()) {
      return L"";
    }
    return instances[i].Version.data();
  }

  std::wstring_view InstallVersion(int i) const {
    if (i < 0 || i >= instances.size()) {
      return L"0";
    }
    return instances[i].Version;
  }
  std::wstring_view InstanceId(int i) const {
    if (i < 0 || i >= instances.size()) {
      return L"-";
    }
    return instances[i].InstanceId;
  }

private:
  container_t instances;
  bool EnterpriseWDK(std::wstring_view ewdkroot, clangbuilder::VSInstance &vsi);
};

class Settings {
public:
  using invoke_t = std::function<void(const std::wstring &)>;
  Settings() = default;
  Settings(const Settings &) = delete;
  Settings &operator=(const Settings &) = delete;
  bool Initialize(std::wstring_view root, const invoke_t &call);
  std::wstring PwshExePath();
  std::wstring_view EnterpriseWDK() const { return ewdkroot; }
  std::wstring_view Terminal() const { return terminal; }

private:
  bool InitializeWindowsTerminal();
  std::wstring ewdkroot;
  std::wstring terminal;
};

#endif


text:
void * proc();

@interface NSConstantString
@end

@interface Frob
@end

@interface Frob1
@end

void * foo()
{
  @try {
    return proc();
  }
  @catch (Frob* ex) {
    @throw;
  }
  @catch (Frob1* ex) {
    @throw proc();
  }
  @finally {
    @try {
      return proc();
    }
    @catch (Frob* ex) {
      @throw 1,2; // expected-error {{@throw requires an Objective-C object type ('int' invalid)}} \
				  // expected-warning {{expression result unused}}
    }
    @catch (float x) {  // expected-error {{@catch parameter is not a pointer to an interface type}}

    }
    @catch(...) {
      @throw (4,3,proc()); // expected-warning {{expression result unused}} \
						   // expected-warning {{expression result unused}}
    }
  }

  @try {  // expected-error {{@try statement without a @catch and @finally clause}}
    return proc();
  }
}

void bar()
{
  @try {}// expected-error {{@try statement without a @catch and @finally clause}}
  @"s"; //  expected-warning {{result unused}}
}

void baz()
{
  @try {}// expected-error {{@try statement without a @catch and @finally clause}}
  @try {}
  @finally {}
}

void noTwoTokenLookAheadRequiresABitOfFancyFootworkInTheParser() {
    @try {
        // Do something
    } @catch (...) {}
    @try {
        // Do something
    } @catch (...) {}
    return;
}


text:
package it.geosolutions.jaiext.piecewise;

/**
 * {@link MathTransformation} implementation for single-dimensional operations
 *
 * @author Nicola Lagomarsini geosolutions
 *
 */
public class SingleDimensionTransformation implements MathTransformation {

    public static final SingleDimensionTransformation IDENTITY = new SingleDimensionTransformation(
            1, 0);

    protected SingleDimensionTransformation(double scale, double offset) {
        this.scale = scale;
        this.offset = offset;
    }

    public double getScale() {
        return scale;
    }

    public void setScale(double scale) {
        this.scale = scale;
    }

    public double getOffset() {
        return offset;
    }

    public void setOffset(double offset) {
        this.offset = offset;
    }

    /** Scale transformation parameter*/
    protected double scale;

    /** Offset transformation parameter*/
    protected double offset;

    private MathTransformation inverse;

    public double transform(double value) {
        return offset + scale * value;
    }

    public double derivative(double value) {
        return scale;
    }

    public int getSourceDimensions() {
        return 1;
    }

    public int getTargetDimensions() {
        return 1;
    }

    public MathTransformation inverseTransform() {
        if (inverse == null) {
            if (isIdentity()) {
                inverse = this;
            } else if (scale != 0) {
                final SingleDimensionTransformation inverse;
                inverse = create(1 / scale, -offset / scale);
                inverse.inverse = this;
                this.inverse = inverse;
            } else {
                throw new UnsupportedOperationException("Unable to invert such transformation");
            }
        }
        return inverse;
    }

    public boolean isIdentity() {
        return isIdentity(0);
    }

    /**
     * Returns true if the transformation is an identity, with a tolerance value
     */
    public boolean isIdentity(double tolerance) {
        tolerance = Math.abs(tolerance);
        return Math.abs(offset) <= tolerance && Math.abs(scale - 1) <= tolerance;
    }

    /**
     * Creates a {@link SingleDimensionTransformation} instance based on the input scale and offset
     *
     * @param scale
     * @param offset
     * @return
     */
    public static SingleDimensionTransformation create(double scale, double offset) {
        if (scale == 0) {
            return new ConstantTransform(offset);
        }
        if (scale == 1 && offset == 0) {
            return IDENTITY;
        }
        return new SingleDimensionTransformation(scale, offset);
    }

    public Position transform(Position ptSrc, Position ptDst) {
        if (ptDst == null) {
            ptDst = new Position();
        }
        ptDst.setOrdinatePosition(transform(ptSrc.getOrdinatePosition()));
        return ptDst;
    }

    /**
     * {@link SingleDimensionTransformation} extension defining Constant transformations
     */
    public static class ConstantTransform extends SingleDimensionTransformation {

        protected ConstantTransform(double offset) {
            super(0, offset);
        }

        public double transform(double value) {
            return offset;
        }
    }
}


text:
'use strict';

const ipc=require('../../../node-ipc');
const process=require('process');
const dieAfter=30000;
const messageDelay=900;

//die after 60 seconds
setTimeout(
    function killServerProcess(){
        process.exit(0);
    },
    dieAfter
);

ipc.config.id = 'unixServerSync';
ipc.config.retry= 1500;
ipc.config.silent=true;

ipc.serve(
    function serverStarted(){
        let ready=false;

        ipc.server.on(
            'message',
            function gotMessage(data,socket){
                if(ready){
                    ipc.server.emit(
                        socket,
                        'message',
                        {
                            id      : ipc.config.id,
                            message : 'Error, client not wating for server response before sending request.'
                        }
                    );
                }
                ready=true;

                setTimeout(
                    function delayedMessage(){
                        ready=false;
                        ipc.server.emit(
                            socket,
                            'message',
                            {
                                id      : ipc.config.id,
                                message : 'Response from unix server'
                            }
                        );
                    },
                    messageDelay
                );
            }
        );
    }
);

ipc.server.start();


text:
<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.0" xml:base="./" xml:id="wb.WorkbenchIntegration"
  xsi:schemaLocation="http://docbook.org/ns/docbook http://www.docbook.org/xml/5.0/xsd/docbook.xsd http://www.w3.org/1999/xlink http://www.docbook.org/xml/5.0/xsd/xlink.xsd"
  xmlns="http://docbook.org/ns/docbook" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink"
  xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:ns="http://docbook.org/ns/docbook">

  <title>Workbench Integration</title>

  <xi:include href="RemoteAPI/REST.xml"/>

</chapter>


text:
package org.hisp.dhis.oum.action.organisationunitgroup;

import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
import org.hisp.dhis.organisationunit.OrganisationUnitGroup;
import org.hisp.dhis.organisationunit.OrganisationUnitGroupService;
import org.hisp.dhis.paging.ActionPagingSupport;

/**
 * @author Torgeir Lorange Ostby
 * @version $Id: GetOrganisationUnitGroupListAction.java 1898 2006-09-22 12:06:56Z torgeilo $
 */
public class GetOrganisationUnitGroupListAction
    extends ActionPagingSupport<OrganisationUnitGroup>
{
    // -------------------------------------------------------------------------
    // Dependencies
    // -------------------------------------------------------------------------

    private OrganisationUnitGroupService organisationUnitGroupService;

    public void setOrganisationUnitGroupService( OrganisationUnitGroupService organisationUnitGroupService )
    {
        this.organisationUnitGroupService = organisationUnitGroupService;
    }

    // -------------------------------------------------------------------------
    // Input & Output
    // -------------------------------------------------------------------------

    private List<OrganisationUnitGroup> organisationUnitGroups = new ArrayList<>();

    public List<OrganisationUnitGroup> getOrganisationUnitGroups()
    {
        return organisationUnitGroups;
    }

    private String key;

    public String getKey()
    {
        return key;
    }

    public void setKey( String key )
    {
        this.key = key;
    }

    // -------------------------------------------------------------------------
    // Action implementation
    // -------------------------------------------------------------------------

    @Override
    public String execute()
        throws Exception
    {
        if ( isNotBlank( key ) ) // Filter on key only if set
        {
            this.paging = createPaging( organisationUnitGroupService.getOrganisationUnitGroupCountByName( key ) );

            organisationUnitGroups = organisationUnitGroupService.getOrganisationUnitGroupsBetweenByName( key, paging.getStartPos(), paging.getPageSize() );
        }
        else
        {
            this.paging = createPaging( organisationUnitGroupService.getOrganisationUnitGroupCount() );

            organisationUnitGroups = organisationUnitGroupService.getOrganisationUnitGroupsBetween( paging.getStartPos(), paging.getPageSize() );
        }

        Collections.sort( organisationUnitGroups, IdentifiableObjectNameComparator.INSTANCE );

        return SUCCESS;
    }
}


text:
using LiveSplit.Model.Input;
using System;

namespace LiveSplit.Model
{
    public class DoubleTapPrevention : ITimerModel
    {
        public LiveSplitState CurrentState
        {
            get
            {
                return InternalModel.CurrentState;
            }
            set
            {
                InternalModel.CurrentState = value;
            }
        }

        public ITimerModel InternalModel { get; set; }

        public event EventHandler OnSplit { add { InternalModel.OnSplit += value; } remove { InternalModel.OnSplit -= value; } }

        public event EventHandler OnUndoSplit { add { InternalModel.OnUndoSplit += value; } remove { InternalModel.OnUndoSplit -= value; } }

        public event EventHandler OnSkipSplit { add { InternalModel.OnSkipSplit += value; } remove { InternalModel.OnSkipSplit -= value; } }

        public event EventHandler OnStart { add { InternalModel.OnStart += value; } remove { InternalModel.OnStart -= value; } }

        public event EventHandlerT<TimerPhase> OnReset { add { InternalModel.OnReset += value; } remove { InternalModel.OnReset -= value; } }

        public event EventHandler OnPause { add { InternalModel.OnPause += value; } remove { InternalModel.OnPause -= value; } }

        public event EventHandler OnResume { add { InternalModel.OnResume += value; } remove { InternalModel.OnResume -= value; } }

        public event EventHandler OnScrollUp { add { InternalModel.OnScrollUp += value; } remove { InternalModel.OnScrollUp -= value; } }

        public event EventHandler OnScrollDown { add { InternalModel.OnScrollDown += value; } remove { InternalModel.OnScrollDown -= value; } }

        public event EventHandler OnSwitchComparisonPrevious { add { InternalModel.OnSwitchComparisonPrevious += value; } remove { InternalModel.OnSwitchComparisonPrevious -= value; } }

        public event EventHandler OnSwitchComparisonNext { add { InternalModel.OnSwitchComparisonNext += value; } remove { InternalModel.OnSwitchComparisonNext -= value; } }

        public DoubleTapPrevention(ITimerModel model)
        {
            InternalModel = model;
        }

        protected bool CheckDoubleTap()
        {
            TimeSpan? lastSplit = null;
            if (CurrentState.Settings.DoubleTapPrevention)
            {
                var index = CurrentState.CurrentSplitIndex - 1;
                while (index >= 0)
                {
                    if (CurrentState.Run[index].SplitTime.RealTime != null)
                    {
                        lastSplit = CurrentState.Run[index].SplitTime.RealTime.Value;
                        break;
                    }
                    index--;
                }
            }
            if (!CurrentState.Settings.DoubleTapPrevention
                || (CurrentState.CurrentPhase == TimerPhase.Running
                && (lastSplit == null || TimeStamp.Now - CurrentState.StartTime > lastSplit + new TimeSpan(0, 0, 0, 0, 300))
                && CurrentState.CurrentTime.RealTime > CurrentState.PauseTime + new TimeSpan(0, 0, 0, 0, 300))
                || (CurrentState.CurrentPhase == TimerPhase.Paused
                && TimeStamp.Now - CurrentState.StartTime > CurrentState.PauseTime + new TimeSpan(0, 0, 0, 0, 300))
                || (CurrentState.CurrentPhase == TimerPhase.Ended
                && TimeStamp.Now - CurrentState.StartTime > CurrentState.CurrentTime.RealTime + new TimeSpan(0, 0, 0, 0, 300))
                || (CurrentState.CurrentPhase == TimerPhase.NotRunning
                && TimeStamp.Now - CurrentState.StartTime > new TimeSpan(0, 0, 0, 0, 300)))
                return true;
            return false;
        }

        public void Start()
        {
            if (CheckDoubleTap())
                InternalModel.Start();
        }

        public void Split()
        {
            if (CheckDoubleTap())
                InternalModel.Split();
        }

        public void SkipSplit()
        {
            if (CheckDoubleTap())
                InternalModel.SkipSplit();
        }

        public void UndoSplit()
        {
            if (CheckDoubleTap())
                InternalModel.UndoSplit();
        }

        public void Reset()
        {
            Reset(true);
        }

        public void Reset(bool updateSplits = true)
        {
            if (CheckDoubleTap())
                InternalModel.Reset(updateSplits);
        }

        public void Pause()
        {
            if (CheckDoubleTap())
                InternalModel.Pause();
        }

        public void ScrollUp()
        {
            InternalModel.ScrollUp();
        }

        public void ScrollDown()
        {
            InternalModel.ScrollDown();
        }

        public void SwitchComparisonPrevious()
        {
            InternalModel.SwitchComparisonPrevious();
        }

        public void SwitchComparisonNext()
        {
            InternalModel.SwitchComparisonNext();
        }

        public void InitializeGameTime()
        {
            InternalModel.InitializeGameTime();
        }
    }
}


text:
package com.hiqes.android.demopermissionsm.util;

import android.util.Log;

public class AndroidLogWriter implements Logger.LoggerWriter {
    @Override
    public void writeEntry(int priority, String tag, String msg) {
        Log.println(priority, tag, msg);
    }
}


text:
<!DOCTYPE HTML>

		<title>Film Review · Kevin Li</title>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<meta name="author" content="Kevin Li">
		<meta name="description" content="Personal Website, Portfolio, and Blog">
		<meta http-equiv="content-language" content="en-us" />

		<meta name="og:site_name" content="Kevin Li">
		<meta name="og:title" content="Film Review">
		<meta name="og:url" content="http://kevinwli.com/categories/film-review/">
		<meta name="og:image" content="http://kevinwli.com/images/https://res.cloudinary.com/lilingkai/image/upload/s--tB1TDmk3--/c_scale,q_jpegmini:1,w_1600/v1492638792/Kevin_vk8jrp.jpg">

		<meta name="generator" content="Hugo 0.54.0" />

		<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
		<link rel="stylesheet" href="http://kevinwli.com/css/main.css" />

		<link href="http://kevinwli.com/categories/film-review/index.xml" rel="alternate" type="application/rss+xml" title="Kevin Li" />
		<link href="http://kevinwli.com/categories/film-review/index.xml" rel="feed" type="application/rss+xml" title="Kevin Li" />

		<link rel="favicon" href="http://res.cloudinary.com/lilingkai/image/upload/v1480470082/favicon_v0tkdd.png">

Kevin Li
 Creator, Developer, Musician

Home

Resume

Blog

        Murder Mystery

<time datetime="2019-07-21 00:00:00 +0000 UTC">2019-07-21</time>

        Film Review

       Murder Mystery
       ·

       Kyle Newacheck
       ·

       Adam Sandler
       ·

       Jennifer Aniston
       ·

       PG-13
       ·

       2019
       ·

       PROJECT-FILM-52

Like my ancestors used to say, "with Adam Sandler, you can't expect a good movie, but you can expect a good time". Ok, they didn't say that exactly, but it perfectly describes "Murder Mystery", a film that could maybe make your otherwise uneventful Tuesday night somewhat entertaining.

        Always Be My Maybe

<time datetime="2019-06-14 00:00:00 +0000 UTC">2019-06-14</time>

        Film Review

       Always Be My Maybe
       ·

       Nahnatchka Khan
       ·

       Ali Wong
       ·

       Randall Park
       ·

       Keanu Reeves
       ·

       Daniel Dae Kim
       ·

       James Saito
       ·

       PG-13
       ·

       2019
       ·

       PROJECT-FILM-52

Last month, Netflix released its much anticipated film, "Always Be My Maybe", and adds yet another notch to its growing list of original romantic comedies. While I always appreciate when a modern film is led by an Asian cast, I can't help but wish the film was more creative and cohesive.

        Avengers: Endgame

<time datetime="2019-05-22 00:00:00 +0000 UTC">2019-05-22</time>

        Film Review

       Avengers
       ·

       Endgame
       ·

       Robert Downey Jr
       ·

       Chris Evans
       ·

       Mark Ruffalo
       ·

       Chris Hemsworth
       ·

       Scarlett Johansson
       ·

       Jeremy Renner
       ·

       Don Cheadle
       ·

       Paul Rudd
       ·

       PG-13
       ·

       2019
       ·

       Poops&Praises
       ·

       PROJECT-FILM-52

Over 10 years of movies have led up to the "Avengers: Endgame", and the Russo's deliver a satisfying and enjoyable conclusion for their most loyal fans.

        Guava Island

<time datetime="2019-05-08 00:00:00 +0000 UTC">2019-05-08</time>

        Film Review

       Guava Island
       ·

       Hiro Murai
       ·

       Donald Glover
       ·

       Rihanna
       ·

       Leticia Wright
       ·

       Nonso Anozie
       ·

       TV-MA
       ·

       2019
       ·

       PROJECT-FILM-52

Donald Glover released his latest artistic endeavor last month on Amazon Prime, and this time it's a short film by the name of "Guava Island". Most art that Donald churns out is of high quality, and for the most part, "Guava Island" is no exception. Yet, there is a feeling of squandered opportunities here that make it feel less like a powerful short film and more like a long, self-glorifying music video.

        The Perfect Date

<time datetime="2019-04-21 00:00:00 +0000 UTC">2019-04-21</time>

        Film Review

       The Perfect Date
       ·

       Chris Nelson
       ·

       Noah Centineo
       ·

       Laura Marano
       ·

       Odiseas Georgiadis
       ·

       Camila Mendes
       ·

       TV-14
       ·

       2019
       ·

       PROJECT-FILM-52

Noah Centineo plays another fake boyfriend in yet another Netflix teenage rom-com in "The Perfect Date", but does this one warrant your time? The short answer: no.

        Unicorn Store

<time datetime="2019-04-12 00:00:00 +0000 UTC">2019-04-12</time>

        Film Review

       Unicorn Store
       ·

       Brie Larson
       ·

       Samuel L. Jackson
       ·

       Joan Cusack
       ·

       Bradley Whitford
       ·

       Mamoudou Athie
       ·

       TV-PG
       ·

       2017
       ·

       Poops&Praises
       ·

       PROJECT-FILM-52

This week, we return back to good old Netflix to find our movie to watch, as well as bring back another edition of "Poops & Praises", a style of review where I just list what I liked (praises) and what I didn't like (poops). Warning, there are mild spoilers ahead.

        The Favourite

<time datetime="2019-04-02 00:00:00 +0000 UTC">2019-04-02</time>

        Film Review

       The Favourite
       ·

       Yorgos Lanthimos
       ·

       Rachel Weisz
       ·

       Emma Stone
       ·

       Olivia Colman
       ·

       R
       ·

       2018
       ·

       PROJECT-FILM-52

Yorgos Lanthimos' latest film, "The Favourite" is a critically acclaimed and highly divisive Best Picture nominee, and after watching, I can certainly see why. This is an English tea time snack with snappy bite and wickedly dark aftertaste.

        Captain Marvel

<time datetime="2019-03-24 00:00:00 +0000 UTC">2019-03-24</time>

        Film Review

       Captain Marvel
       ·

       Anna Boden
       ·

       Ryan Fleck
       ·

       Brie Larson
       ·

       Samuel L. Jackson
       ·

       Ben Mendelsohn
       ·

       PG-13
       ·

       2019
       ·

       Poops&Praises
       ·

       PROJECT-FILM-52

Here comes another "Poops & Praises", a style of review where I just list what I liked (praises) and what I didn't like (poops). Warning, there are mild spoilers ahead.

        Fantastic Beasts: The Crimes of Grindelwald

<time datetime="2019-03-24 00:00:00 +0000 UTC">2019-03-24</time>

        Film Review

       Fantastic Beasts The Crimes of Grindelwald
       ·

       David Yates
       ·

       Johnny Depp
       ·

       Eddie Redmayne
       ·

       Ezra Miller
       ·

       Jude Law
       ·

       PG-13
       ·

       2018
       ·

       PROJECT-FILM-52

"The Crimes of Grindelwald" is the second installment of five planned movies (yes, you read it correctly) in the "Fantastic Beasts" Harry Potter spin-off/prequel series. While the first film showed some promise, the second film isn't able to reproduce those results.

        Destination Wedding

<time datetime="2019-03-11 00:00:00 +0000 UTC">2019-03-11</time>

        Film Review

       Destination Wedding
       ·

       Victor Levin
       ·

       Keanu Reeves
       ·

       Winona Ryder
       ·

       R
       ·

       2018
       ·

       Poops&Praises
       ·

       PROJECT-FILM-52

This week's review brings the second installment in "Poops & Praises", a style of review where I just list what I liked (praises) and what I didn't like (poops).

            Older »

GitHub

Linkedin

YouTube

Email

RSS

© Kevin Li

Design: HTML5 UP


text:
import numpy as np
from parameterized import parameterized_class
import unittest

from selfdrive.controls.lib.drive_helpers import VCruiseHelper, V_CRUISE_MIN, V_CRUISE_MAX, V_CRUISE_ENABLE_MIN, IMPERIAL_INCREMENT
from cereal import car
from common.conversions import Conversions as CV
from common.params import Params
from selfdrive.test.longitudinal_maneuvers.maneuver import Maneuver

ButtonEvent = car.CarState.ButtonEvent
ButtonType = car.CarState.ButtonEvent.Type

def run_cruise_simulation(cruise, t_end=20.):
  man = Maneuver(
    '',
    duration=t_end,
    initial_speed=max(cruise - 1., 0.0),
    lead_relevancy=True,
    initial_distance_lead=100,
    cruise_values=[cruise],
    prob_lead_values=[0.0],
    breakpoints=[0.],
  )
  valid, output = man.evaluate()
  assert valid
  return output[-1, 3]

class TestCruiseSpeed(unittest.TestCase):
  def test_cruise_speed(self):
    params = Params()
    for e2e in [False, True]:
      params.put_bool("ExperimentalMode", e2e)
      for speed in np.arange(5, 40, 5):
        print(f'Testing {speed} m/s')
        cruise_speed = float(speed)

        simulation_steady_state = run_cruise_simulation(cruise_speed)
        self.assertAlmostEqual(simulation_steady_state, cruise_speed, delta=.01, msg=f'Did not reach {speed} m/s')

# TODO: test pcmCruise
@parameterized_class(('pcm_cruise',), [(False,)])
class TestVCruiseHelper(unittest.TestCase):
  def setUp(self):
    self.CP = car.CarParams(pcmCruise=self.pcm_cruise)  # pylint: disable=E1101
    self.v_cruise_helper = VCruiseHelper(self.CP)
    self.reset_cruise_speed_state()

  def reset_cruise_speed_state(self):
    # Two resets previous cruise speed
    for _ in range(2):
      self.v_cruise_helper.update_v_cruise(car.CarState(cruiseState={"available": False}), enabled=False, is_metric=False)

  def enable(self, v_ego):
    # Simulates user pressing set with a current speed
    self.v_cruise_helper.initialize_v_cruise(car.CarState(vEgo=v_ego))

  def test_adjust_speed(self):
    """
    Asserts speed changes on falling edges of buttons.
    """

    self.enable(V_CRUISE_ENABLE_MIN * CV.KPH_TO_MS)

    for btn in (ButtonType.accelCruise, ButtonType.decelCruise):
      for pressed in (True, False):
        CS = car.CarState(cruiseState={"available": True})
        CS.buttonEvents = [ButtonEvent(type=btn, pressed=pressed)]

        self.v_cruise_helper.update_v_cruise(CS, enabled=True, is_metric=False)
        self.assertEqual(pressed, self.v_cruise_helper.v_cruise_kph == self.v_cruise_helper.v_cruise_kph_last)

  def test_rising_edge_enable(self):
    """
    Some car interfaces may enable on rising edge of a button,
    ensure we don't adjust speed if enabled changes mid-press.
    """

    # NOTE: enabled is always one frame behind the result from button press in controlsd
    for enabled, pressed in ((False, False),
                             (False, True),
                             (True, False)):
      CS = car.CarState(cruiseState={"available": True})
      CS.buttonEvents = [ButtonEvent(type=ButtonType.decelCruise, pressed=pressed)]
      self.v_cruise_helper.update_v_cruise(CS, enabled=enabled, is_metric=False)
      if pressed:
        self.enable(V_CRUISE_ENABLE_MIN * CV.KPH_TO_MS)

      # Expected diff on enabling. Speed should not change on falling edge of pressed
      self.assertEqual(not pressed, self.v_cruise_helper.v_cruise_kph == self.v_cruise_helper.v_cruise_kph_last)

  def test_resume_in_standstill(self):
    """
    Asserts we don't increment set speed if user presses resume/accel to exit cruise standstill.
    """

    self.enable(0)

    for standstill in (True, False):
      for pressed in (True, False):
        CS = car.CarState(cruiseState={"available": True, "standstill": standstill})
        CS.buttonEvents = [ButtonEvent(type=ButtonType.accelCruise, pressed=pressed)]
        self.v_cruise_helper.update_v_cruise(CS, enabled=True, is_metric=False)

        # speed should only update if not at standstill and button falling edge
        should_equal = standstill or pressed
        self.assertEqual(should_equal, self.v_cruise_helper.v_cruise_kph == self.v_cruise_helper.v_cruise_kph_last)

  def test_set_gas_pressed(self):
    """
    Asserts pressing set while enabled with gas pressed sets
    the speed to the maximum of vEgo and current cruise speed.
    """

    for v_ego in np.linspace(0, 100, 101):
      self.reset_cruise_speed_state()
      self.enable(V_CRUISE_ENABLE_MIN * CV.KPH_TO_MS)

      # first decrement speed, then perform gas pressed logic
      expected_v_cruise_kph = self.v_cruise_helper.v_cruise_kph - IMPERIAL_INCREMENT
      expected_v_cruise_kph = max(expected_v_cruise_kph, v_ego * CV.MS_TO_KPH)  # clip to min of vEgo
      expected_v_cruise_kph = float(np.clip(round(expected_v_cruise_kph, 1), V_CRUISE_MIN, V_CRUISE_MAX))

      CS = car.CarState(vEgo=float(v_ego), gasPressed=True, cruiseState={"available": True})
      CS.buttonEvents = [ButtonEvent(type=ButtonType.decelCruise, pressed=False)]
      self.v_cruise_helper.update_v_cruise(CS, enabled=True, is_metric=False)

      # TODO: fix skipping first run due to enabled on rising edge exception
      if v_ego == 0.0:
        continue
      self.assertEqual(expected_v_cruise_kph, self.v_cruise_helper.v_cruise_kph)

  def test_initialize_v_cruise(self):
    """
    Asserts allowed cruise speeds on enabling with SET.
    """

    for v_ego in np.linspace(0, 100, 101):
      self.reset_cruise_speed_state()
      self.assertFalse(self.v_cruise_helper.v_cruise_initialized)

      self.enable(float(v_ego))
      self.assertTrue(V_CRUISE_ENABLE_MIN <= self.v_cruise_helper.v_cruise_kph <= V_CRUISE_MAX)
      self.assertTrue(self.v_cruise_helper.v_cruise_initialized)

if __name__ == "__main__":
  unittest.main()


text:
Alerter is a UMD JavaScript module for displaying arbitrary messaging to communicate certain states in a web app.

An `Alerter()` instance does two things;
1) Injects alert messages along with markup templates into your page, and removes the markup when the alerts are dismissed.
2) Emits events when alerts are created or dismissed.

# Getting the Module
From GitHub;
- Download [the latest release](https://github.com/blocks/alerter/releases)

Using npm;
- `npm install blocks-alerter`

Using Bower;
- [Install using the tarball URL](http://bower.io/docs/api/#install) (best option)
- Or use browserify or webpack to consume the CommonJS module

# Quick Start
To get started, you'll need to include the script on your page. To create an `Alerter()` instance you can do;

```
var myAlerter = new Alerter();
```

You can then create an alert like this;

```
var myAlert = myAlerter.create({message: 'Hello!'});
```

And dismiss the alert like this;

```
myAlerter.dismiss(myAlert);
```

# Advanced Usage

## Options
There are several options available when you initialize a new `Alerter()` object;

### `prependTo`
A DOM element, jQuery element, or selector string to refer to the placeholder element, where alerts will be injected. By default, alerts will be injected at the top of the `<body>`.

### `template`
Out of the box, the module will generate BEM markup with the namespace `alert` that contains all of the markup needed to display the alert. If you want to customize the markup, you can pass in a *compiled* handlebars template. (Defaults to `false`).

## Methods

### `Alerter.create(optionsHash)`
Creates a new alert DOM object and injects it into the page via the `Alerter()` object. You can pass the following options in;
- `message` **(Required)** this is a string with the message you want to display. You can use plain text or an HTML string with inline tags.
- `detail` This is a string with more details related to the main message.
- `errors` This is an array of strings. It will be displayed as a `<ul>` in the default template, and can be useful for listing specific items that need to be addressed by the user.
- `dismissable`  Boolean. Whether or not to display a close button on the alert. Defaults to `false`.
- `type` is a string and allows you to choose the class of alert which can be used for CSS styling, attaching events, etc. This string will be combined with the BEM namespace and used to generate a BEM class name in the inserted markup. For example, passing `'warning'` as the type will result in the alert element having a class name of `alert--warning`. The default is `false`, which will result in a class name of `alert`.

### `Alerter.dismiss(alert)`
When this method is called on an `Alerter` instance, it dismisses all alerts which originated from that instance. If you want to dismiss one specific alert, you can pass in the alert instance itself.

## Events
Every instance of `Alerter()` will emit events when an alert is created or dismissed. You can listen for these events to assist with transitions, modal dialogs, cleanup, etc in your app.

### `alertCreated`
Fires whenever an alert is created. Contains a payload object with the alert message and other data.

### `alertDismissed`
Fires whenever an alert message is dismissed. Contains a payload object with the unique id of the alert that was dismissed.

# Testing the Module
If you want to build and test this module yourself, you can do so by running `gulp` to build the module and start a server or `gulp test` to build the module, start a server, open a tunnel to BrowserStack and run mocha tests. Before you can run mocha tests, you'll have to define a BrowserStack key and username in `/test/selenium-driver.js` and BrowserStack key in `/gulp/startBrowserStackTunnel.js`.


text:
using System;
using System.Collections.Generic;
using System.Text;
using FlatRedBall.Utilities;

namespace FlatRedBall.Instructions
{
    #region XML Docs
    /// <summary>
    /// Represents a set of KeyframeLists which can be applied to objects or
    /// used to perform scripted events.
    /// </summary>
    /// <remarks>
    /// When used to perform scripted events, InstructionSets can be compared
    /// to texture animation.  There are many levels of Lists in an InstructionSet.
    /// The following comparison to AnimationChainLists provides some clarity to the
    /// layers:
    /// <para>
    /// InstructionSet (List of KeyframeLists) : AnimationChainList (List of AnimationChains)
    /// </para>
    /// <para>
    /// KeyframeList (List of Keyframes - aka InstructionLists) : AnimationChain (List of AnimationFrames)
    /// </para>
    /// <para>
    /// InstructionList (Applied to an object to change any properties) : AnimationFrame (Applied to an object to change its appearance);
    /// </para>
    /// </remarks>
    #endregion
    public class InstructionSet : List<KeyframeList>, INameable
    {
        #region Fields
        string mName;
        #endregion

        #region Properties

        #region XML Docs
        /// <summary>
        /// Gets a KeyframeList by name.  Returns null if none is found
        /// </summary>
        /// <param name="keyframeListName">Name of the KeyframeList to return.</param>
        /// <returns>Reference to the KeyframeList with the specified name.</returns>
        #endregion
        public KeyframeList this[string keyframeListName]
        {
            get
            {
                for (int i = this.Count - 1; i > -1; i--)
                {
                    if (this[i].Name == keyframeListName)
                    {
                        return this[i];
                    }
                }

                //nothing found, return null
                return null;
            }
        }

        public string Name
        {
            get { return mName; }
            set { mName = value; }
        }

        #endregion
    }
}


text:
package com.google.common.graph;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.collect.Ordering;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.TreeMap;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/** Tests for {@link MapIteratorCache} and {@link MapRetrievalCache}. */
@AndroidIncompatible
// TODO(cpovirk): Figure out Android JUnit 4 support. Does it work with Gingerbread? @RunWith?
@RunWith(Parameterized.class)
public final class MapCacheTest {
  private final MapIteratorCache<String, String> mapCache;

  public MapCacheTest(MapIteratorCache<String, String> mapCache) {
    this.mapCache = mapCache;
  }

  @Parameters
  public static Collection<Object[]> parameters() {
    Comparator<String> nullsLast = Ordering.natural().nullsLast();

    return Arrays.asList(
        new Object[][] {
          {new MapIteratorCache<String, String>(new HashMap<String, String>())},
          {new MapIteratorCache<String, String>(new TreeMap<String, String>(nullsLast))},
          {new MapRetrievalCache<String, String>(new HashMap<String, String>())},
          {new MapRetrievalCache<String, String>(new TreeMap<String, String>(nullsLast))}
        });
  }

  @Before
  public void init() {
    mapCache.clear();
  }

  @Test
  public void testKeySetIterator() {
    mapCache.put("A", "A_value");
    mapCache.put("B", "B_value");
    mapCache.put("C", "C_value");

    assertThat(mapCache.unmodifiableKeySet()).hasSize(3);
    for (String key : mapCache.unmodifiableKeySet()) {
      assertThat(mapCache.get(key)).isEqualTo(key + "_value");
    }
  }

  @Test
  public void testPutNewValue() {
    assertThat(mapCache.put("key", "value")).isNull();
    assertThat(mapCache.get("key")).isEqualTo("value"); // ensure key/value is cached
    assertThat(mapCache.put("key", "new value")).isEqualTo("value");
    assertThat(mapCache.get("key")).isEqualTo("new value");
  }

  @Test
  public void testRemoveEqualKeyWithDifferentReference() {
    String fooReference1 = new String("foo");
    String fooReference2 = new String("foo");
    assertThat(fooReference1).isNotSameInstanceAs(fooReference2);

    assertThat(mapCache.put(fooReference1, "bar")).isNull();
    assertThat(mapCache.get(fooReference1)).isEqualTo("bar"); // ensure first reference is cached
    assertThat(mapCache.remove(fooReference2)).isEqualTo("bar");
    assertThat(mapCache.get(fooReference1)).isNull();
  }

  @Test
  public void testHandleNulls() {
    mapCache.put("foo", "bar");
    mapCache.put("non-null key", null);
    mapCache.put(null, "non-null value");

    assertThat(mapCache.get("foo")).isEqualTo("bar");
    assertThat(mapCache.get("non-null key")).isNull();
    assertThat(mapCache.get(null)).isEqualTo("non-null value");

    assertThat(mapCache.containsKey("foo")).isTrue();
    assertThat(mapCache.containsKey("bar")).isFalse();
    assertThat(mapCache.containsKey("non-null key")).isTrue();
    assertThat(mapCache.containsKey(null)).isTrue();

    // Test again - in reverse order.
    assertThat(mapCache.get(null)).isEqualTo("non-null value");
    assertThat(mapCache.get("non-null key")).isNull();
    assertThat(mapCache.get("foo")).isEqualTo("bar");
  }
}


text:
package org.dspace.authenticate;

import org.apache.log4j.Logger;
import org.apache.tools.ant.taskdefs.Get;
import org.dspace.authority.orcid.Orcid;
import org.dspace.authority.orcid.model.Bio;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.eperson.EPerson;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.sql.SQLException;

/**
 *
 * @author mdiggory at atmire.com
 */
public class OAuthAuthenticationMethod implements AuthenticationMethod{

    /** log4j category */
    private static Logger log = Logger.getLogger(OAuthAuthenticationMethod.class);

    @Override
    public boolean canSelfRegister(Context context, HttpServletRequest request, String username) throws SQLException {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void initEPerson(Context context, HttpServletRequest request, EPerson eperson) throws SQLException {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean allowSetPassword(Context context, HttpServletRequest request, String username) throws SQLException {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean isImplicit() {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public int[] getSpecialGroups(Context context, HttpServletRequest request) throws SQLException {
        return new int[0];  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public int authenticate(Context context, String username, String password, String realm, HttpServletRequest request) throws SQLException {

        String email = null;

        String orcid = (String) request.getAttribute("orcid");
        String token = (String) request.getAttribute("access_token");
        String refreshToken = (String) request.getAttribute("refresh_token");
        boolean test = "true".equals(request.getParameter("test"));
        if (request == null||orcid==null)
        {
            return BAD_ARGS;
        }

        //get the orcid profile
        Bio bio = null;

        String orcid_api_url = ConfigurationManager.getProperty("authentication-oauth","orcid-api-url");

        Orcid orcidObject = new Orcid(orcid_api_url);

        if(orcid!=null)
        {
            if(token==null||test){
                bio = orcidObject.getBio(orcid);
            }
            else
            {
                bio = orcidObject.getBio(orcid,token);
            }
        }
        //get the email from orcid
        if(bio!=null)
        {
            email = bio.getEmail();

        }

        //Get ORCID profile if they are authenticated (test mode = ?test=true&orcid=[ID]
        //use [orcid]@test.com as the email for test mode
        if(test)
        {
            email = orcid+"@test.com";
        }

        EPerson currentUser = context.getCurrentUser();

        if(orcid!=null)
        {
            //Step 1, check if the orcid id exists or not
            EPerson e = EPerson.findByOrcidId(context,orcid);

            if(e!=null)
            {
               //orcid id already exists

               if(currentUser!=null&&e.getID()==currentUser.getID())
               {
                   //the orcid id already linked to the current user
                   request.getSession().setAttribute("oauth.authenticated",
                           Boolean.TRUE);
                   return AuthenticationMethod.SUCCESS;
               }
               else if(currentUser==null)
               {
                   //the orcid id exists and already linked to the user ,login successful
                   currentUser = e;
                   request.getSession().setAttribute("oauth.authenticated",
                           Boolean.TRUE);
                   context.setCurrentUser(e);
                   return AuthenticationMethod.SUCCESS;
               }
               else
               {
                   //todo:report the exist orcid user
                   request.getSession().setAttribute("exist_orcid",e.getEmail());
                   return BAD_CREDENTIALS;
               }
            }
            else{

            //Step 2, check the current login user
            if (currentUser != null)
            {
                //link the orcid id to the current login user
                currentUser.setMetadata("orcid",orcid);
                currentUser.setMetadata("access_token",token);
                orcid = currentUser.getMetadata("orcid");
                try{
                currentUser.update();
                }catch (Exception exception)
                {
                    log.error("error when link the orcid id:"+orcid+" to current login in user:"+currentUser.getEmail());
                }
                context.commit();
                request.getSession().setAttribute("oauth.authenticated",
                        Boolean.TRUE);
                return AuthenticationMethod.SUCCESS;
            }
            else{

            //step 3, orcid id doen't exist and user does not login, remind user to create user account and then link the orcid
            request.getSession().setAttribute("set_orcid",orcid);
            request.getSession().setAttribute("oauth.authenticated",Boolean.TRUE);
            return BAD_CREDENTIALS;

            }
            }
        }
        else
        {
            return BAD_CREDENTIALS;
        }

    }
    @Override
    public String loginPageURL(Context context, HttpServletRequest request, HttpServletResponse response) {
        if(ConfigurationManager.getBooleanProperty("authentication-oauth","choice-page")){
            return response.encodeRedirectURL(request.getContextPath()
                + "/oauth-login");
        }
        else
        {
            return null;
        }
    }

    @Override
    public String loginPageTitle(Context context) {
        return "org.dspace.authenticate.OAuthAuthentication.title";
    }
}