- if medications.any?
  table[class="auto-layout" id="#{id}"]
    thead
      tr
        th
        th= sort_link_if(treatable.sortable?, search, :drug_name, "Medication")
        th Drug Type
        th Dose
        th Frequency
        th Route
        th Provider
        th Notes
        th= sort_link_if(treatable.sortable?, search, :prescribed_on, "Prescribed on")
        th Prescribed By
        - if include_terminated_column
          th Terminated On
    tbody
      - medications.each do |medication|
        tr
          td
            - if medication.current?
                = link_to "Edit", edit_patient_medication_path(patient, medication), remote: true
                = pipe_separator
                = link_to "Terminate", patient_medication_path(patient, medication), method: :delete,
                    remote: true, data: { confirm: "Are you sure?" }
          td= medication.drug.name
          td= medication.drug_types
          td= medication.dose
          td= medication.frequency
          td= medication.route_name
          td= medication.provider
          td= medication.notes
          td= I18n.l medication.prescribed_on
          td= medication.created_by.full_name
          - if include_terminated_column
            td= I18n.l medication.terminated_on
- else
  p There are no medications in this list.

Allow allow to terminate if medication is not previously terminated

- if medications.any?
  table[class="auto-layout" id="#{id}"]
    thead
      tr
        th
        th= sort_link_if(treatable.sortable?, search, :drug_name, "Medication")
        th Drug Type
        th Dose
        th Frequency
        th Route
        th Provider
        th Notes
        th= sort_link_if(treatable.sortable?, search, :prescribed_on, "Prescribed on")
        th Prescribed By
        - if include_terminated_column
          th Terminated On
    tbody
      - medications.each do |medication|
        tr
          td
            - if medication.current?
                = link_to "Edit", edit_patient_medication_path(patient, medication), remote: true
            - unless medication.terminated?
                = pipe_separator
                = link_to "Terminate", patient_medication_path(patient, medication), method: :delete,
                    remote: true, data: { confirm: "Are you sure?" }
          td= medication.drug.name
          td= medication.drug_types
          td= medication.dose
          td= medication.frequency
          td= medication.route_name
          td= medication.provider
          td= medication.notes
          td= I18n.l medication.prescribed_on
          td= medication.created_by.full_name
          - if include_terminated_column
            td= I18n.l medication.terminated_on
- else
  p There are no medications in this list.


/ Note the caching here relies on study_participant edit/create/destroy touching patient
- cache(patient)
  - participations = Renalware::Research::StudyParticipant.where(participant_id: patient.id).where("joined_on <= ?", Time.zone.now).where("left_on is null or left_on > ?", Time.zone.now)
  = render partial: "renalware/research/alert",
           collection: participations,
           as: :participation

Remove caching of patient alerts


= render 'layouts/head'
= render 'layouts/navbar'
.container
  = render 'layouts/loader'
  = yield
  = render 'layouts/footer'

Add information about the temporary records.

= render 'layouts/head'
= render 'layouts/navbar'
.container
  = render 'layouts/loader'
  small All records and player ids are temporary and will be cleared when steam only QL is released
  = yield
  = render 'layouts/footer'


= form_tag user_registration_path do
  / TODO error message handling
  div role='form'
    div.form-group
      = email_field_tag 'user[email]', nil,
                        :placeholder => 'Email',
                        :class => 'form-control',
                        :autofocus => true
    div.form-group
      = password_field_tag 'user[password]', nil,
                           :placeholder => 'Password',
                           :class => 'form-control'
    div.form-group
      = password_field_tag 'user[password_confirmation]', nil,
                           :placeholder => 'Password confirmation',
                           :class => 'form-control'

    div
      button type='submit' class='btn btn-small btn-primary' Sign up

Add password length hint to modal sign up form

= form_tag user_registration_path do
  / TODO error message handling
  div role='form'
    div.form-group
      = email_field_tag 'user[email]', nil,
                        :placeholder => 'Email',
                        :class => 'form-control',
                        :autofocus => true
    div.form-group
      = password_field_tag 'user[password]', nil,
                           :placeholder => 'Password',
                           :class => 'form-control'
      span.help-block Passwords must contain at least 8 characters.
    div.form-group
      = password_field_tag 'user[password_confirmation]', nil,
                           :placeholder => 'Password confirmation',
                           :class => 'form-control'

    div
      button type='submit' class='btn btn-small btn-primary' Sign up


p
  ' Welcome
  = @email
  ' !
p You have signed up for a Queens' Awards for Enterprise account.

p
  ' You can
  = link_to "confirm your email account here", confirmation_url(@resource, confirmation_token: @token)
  ' .

p If you've not signed up for an account with us, you can ignore this email.

p Thank you,

p The Queen's Awards Office

COPY typo comma on confirmation email

p
  ' Welcome
  = @email
  ' !
p You have signed up for a Queens' Awards for Enterprise account.

p
  ' You can
  = link_to "confirm your email account here", confirmation_url(@resource, confirmation_token: @token)
  ' .

p If you've not signed up for an account with us you can ignore this email.

p Thank you,

p The Queen's Awards Office


li.schedule-single
  - if time_iteration.first?
    .header
      h3
        span #{day.label} -
        |  #{day.date}
  .inner-content
    .left
      .time
        span.fa.fa-clock-o[style="display: inline;"]
        h2 = time.label
      .title
        = render(partial: 'agenda', collection: time.agendas.sort{ |agenda| agenda.room.order }) || 'TBA'

Fix agenda ordering without room

li.schedule-single
  - if time_iteration.first?
    .header
      h3
        span #{day.label} -
        |  #{day.date}
  .inner-content
    .left
      .time
        span.fa.fa-clock-o[style="display: inline;"]
        h2 = time.label
      .title
        = render(partial: 'agenda', collection: time.agendas.sort{ |agenda| agenda.room&.order || 0 }) || 'TBA'


.row
  .small-12.medium-8.large-5.columns
    h3.pad-top-thirty-px.bold Process application
    p You'll need:
    ul
      li the help with fees application form (EX160)
      li the court or tribunal form related to the application
    .actions
      =link_to 'Start now', new_application_path, class: 'button success'

  .small-12.medium-8.large-5.columns
    .info-box
      h3.bold Get Help
      p =link_to t('functions.staff_guide').to_s, guide_path
      p =link_to t('functions.feedback').to_s, feedback_path
      details
        summary
          span.summary Contact us
        div Email: #{link_to Settings.mail.tech_support, "mailto:#{Settings.mail.tech_support}"}

.row
  .small-12.medium-12.large-12.columns
    =render('home/waiting_for_evidence')

.row
  .small-12.medium-12.large-12.columns
    h3.pad-top-thirty-px.bold Manage your office
    p =link_to 'Staff overview', users_path
    p =link_to 'Your Office', current_user.office

Change order of manager dashboard items

.row
  .small-12.medium-8.large-5.columns
    h3.pad-top-thirty-px.bold Process application
    p You'll need:
    ul
      li the help with fees application form (EX160)
      li the court or tribunal form related to the application
    .actions
      =link_to 'Start now', new_application_path, class: 'button success'

  .small-12.medium-8.large-5.columns
    .info-box
      h3.bold Get Help
      p =link_to t('functions.staff_guide').to_s, guide_path
      p =link_to t('functions.feedback').to_s, feedback_path
      details
        summary
          span.summary Contact us
        div Email: #{link_to Settings.mail.tech_support, "mailto:#{Settings.mail.tech_support}"}

.row
  .small-12.medium-12.large-12.columns
    h3.pad-top-thirty-px.bold Manage your office
    p =link_to 'Staff overview', users_path
    p =link_to 'Your Office', current_user.office

.row
  .small-12.medium-12.large-12.columns
    =render('home/waiting_for_evidence')


h1 payments#new

Create the base of new view

= initjs_tag app_name: 'Neighborly', partial: true

.neighborly-balanced-bankaccount-form[data-balanced-bankaccount-form data-balanced-marketplace-id=@balanced_marketplace_id]
  = simple_form_for :payment, url: payments_path, html: { class: 'custom', novalidate: '' } do |f|
    .row
      .large-12.columns.title
        h4 = t('.bankaccount.title')
        p = t('.bankaccount.subtitle')

      .large-12.columns.check-numbers
        = image_tag('payments/check-numbers.png')

      .large-12.columns.account-informations
        .row
          .large-12.columns
            = f.input :account_holder_name

          .large-6.small-6.columns
            = f.input :routing_number

          .large-6.small-6.columns
            = f.input :bank_name, disabled: true

          .large-12.columns
            = f.input :account_number

      .user-informations
        = f.simple_fields_for :user do |fu|
          .large-12.columns.title
            hr
            h4 = t('.billing.title')
            p = t('.billing.subtitle')

      .large-12.columns.terms
        = t('.terms', link: link_to(t('.terms-link'), main_app.terms_path(), data: { 'reveal-id' => 'terms-modal', 'reveal-ajax' => true })).html_safe

      .large-6.columns
        = submit_tag t('.confirm'), class: 'button', data: { disable_with: t('.proccessing') }

      .large-6.columns.text-right.balanced-seal
        = link_to image_tag('https://balancedpowered.s3.amazonaws.com/secured-1-4.png'), 'https://www.balancedpayments.com/'

  #terms-modal.reveal-modal.small.fixed


- model_class = Graph

table class="table table-striped"
  thead
    tr
      th= model_class.human_attribute_name(:id)
      th= model_class.human_attribute_name(:path)
      th= model_class.human_attribute_name(:created_at)
      th=t '.actions', :default => t("helpers.actions")
  tbody
    - @graphs.each do |graph|
      tr
        td= link_to graph.id, graph_path(graph)
        td= link_to graph.path, view_graph_path(graph.path)
        td=l graph.created_at
        td
          = link_to t('.edit', :default => t("helpers.links.edit")), edit_graph_path(graph), :class => 'btn btn-mini'
          '
          = link_to t('.destroy', :default => t("helpers.links.destroy")), graph_path(graph), :method => :delete, :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) }, :class => 'btn btn-mini btn-danger'

= link_to t('.new', :default => t("helpers.links.new")), new_graph_path, :class => 'btn btn-primary'

Fix table's style in the debug page

- model_class = Graph

table class="table table-striped"
  thead
    tr
      th= model_class.human_attribute_name(:id)
      th= model_class.human_attribute_name(:path)
      th= model_class.human_attribute_name(:created_at)
      th=t '.actions', :default => t("helpers.actions")
  tbody
    - @graphs.each do |graph|
      tr
        td= link_to graph.id, graph_path(graph)
        td.word-break-all style="width: 50%;" = link_to graph.path, view_graph_path(graph.path)
        td=l graph.created_at
        td
          = link_to t('.edit', :default => t("helpers.links.edit")), edit_graph_path(graph), :class => 'btn btn-mini'
          '
          = link_to t('.destroy', :default => t("helpers.links.destroy")), graph_path(graph), :method => :delete, :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) }, :class => 'btn btn-mini btn-danger'

= link_to t('.new', :default => t("helpers.links.new")), new_graph_path, :class => 'btn btn-primary'


h1 Looking for a Job?

h2 Our sponsors are usually hiring!
p
  ' Check the
  = link_to "Sponsors Page", page_path('sponsors')
  |.

h2 Networking
p Networking sounds like an MBA buzzword, but it is as easy as coming to a
  meeting and talking about what interests you in software. We encourage you to
  come and ask people about their jobs.


.row
  .container
    h1 Middleman Startaê
    p A Middleman template with Slim, Sass, Coffeescript, Bourbon, Susy, Bower and more
    a.btn href='https://github.com/startae/middleman-startae' See the Github project

Update template description to include hagrid and remove Susy and Bourboun

.row
  .container
    h1 Middleman Startaê
    p A Middleman template with Slim, Sass, Coffeescript, Hagrid, Bower and more
    a.btn href='https://github.com/startae/middleman-startae' See the Github project


Add a customized template for password expired page

= within_admin_layout(title: "Renew your password") do
  = simple_form_for(resource, as: resource_name, url: [resource_name, :password_expired], html: { method: :put }) do |f|
    = f.error_notification
    = custom_devise_error_messages!

    p
      = f.label :current_password, 'Current password'
      br
      = f.password_field :current_password

    p
      = f.label :password, 'New password'
      br
      = f.password_field :password

    p
      = f.label :password_confirmation, 'Confirm new password'
      br
      = f.password_field :password_confirmation

    p = f.button :submit, 'Change my password'


////////////////////////////
// View translation scoping
////////////////////////////
/
/ Just like other code, views should be as DRY as possible. If you use i18n in your application,
/ you know just how quickly things can get out of hand and how often you repeat certain scopes.
/ Coming up with a good translation key strategy is a whole topic by itself but if you have figured
/ it out, this little trick will be helpful for you.
/
/ ActiveSupport gives you `Object#with_options` (http://apidock.com/rails/Object/with_options)
/ which is a kind of argument merging tool. It fits just perfectly with the i18n translate API.

- with_options(scope: 'customers.show') do |i18n|
  / same as t('customers.show.details')
  h2 = i18n.t('details')
  ul
    / same as t('customers.show.list.item_1') etc.
    li = i18n.t('list.item_1')
    li = i18n.t('list.item_2')
    li = i18n.t('list.item_3')


doctype 5
html lang='en'
  head
    meta content='text/html; charset=utf-8' http-equiv='Content-Type'
    meta name='viewport' content='width=device-width,initial-scale=1'
    title = @title.present? ? "#{@title} | Nilgiri" : "Nilgiri"
    = stylesheet_link_tag 'application'
    = javascript_include_tag 'application'
  body
    header
      h1 Nilgiri
    div class='grid'
      = yield
    footer
      p nilgiri


Add an unpublished article with notes about website, Developer Notes

---
title: Developer Notes
tags: Deodorant
disqus_id: demo-article
img: diy-deoderant-long.jpg
published: false
---

h1 Developer Notes

h2 Building the site

p To build the site, use:

middleman build

p It will build to the docs/ directory.  The docs/ directory on the master branch of the repository is automatically set to publish by Github.

h2 Viewing the build

p Because the site expects to be hoster at the root of the webserver, it isn't possible to view the build in the docs/ directory just by using the address relative to localhost (e.g. http://localhost/demo/nature/docs/).

p Instead there is a virtual server mapped on apache for that directory.  You can access it by going to #{ link_to "http://notp", "http://notp" }.


Add missign partial from catarse_bootstrap

- if flash[:alert].present?
  .alert-box.alert.animated.shake
    .large-12.large-centered.columns
      h3= t('failure_title')
      p= flash[:alert]
- elsif resource.errors.present?
  .alert-box.alert.animated.shake
    .large-12.large-centered.columns
      h3= t('failure_title')
      - resource.errors.messages.each do |message|
        p= message[1].to_sentence


---
title: Support
nav: support
---

.content-section-a
  .container
    .row
      .col-lg-12
        h2#gitter Community Chat (Gitter)
        p
          | For quick help, you can try the
          a<> href="https://gitter.im/cucumber/chat" cucumber/chat
          | room hosted at Gitter.
      .col-lg-12
        h2#irc Community Chat (IRC)
        p
          | If you're old school you can try the
          a<> href="irc://irc.freenode.net/cucumber" #cucumber
          | IRC channel on freenode.net
    .row
      .col-lg-12
        h2#community Community mailing list
        p
          | Over 3000 Cucumber users are part of the daily discussions on our
          a<> href="https://groups.google.com/group/cukes" mailing list
          | It's a great place to get your questions answered, and to share your knowledge with others in the community.
            Please respect the
          a<> href="/posting-rules" posting rules.
    .row
      .col-lg-12
        h2#premium Premium Support
        p
          | When you want guaranteed accesss to prompt, expert help, you need premium support.
    .row.text-center.hidden-xs
      a.btn.btn-lg.btn-primary href="/CucumberPaidSupportPlans.pdf"  Download our premium support prices
    .row.text-center.visible-xs
      .jumbotron
        | Download our
        a href="/CucumberPaidSupportPlans.pdf" premium support prices

Move mailing list up - it's the primary forum

---
title: Support
nav: support
---

.content-section-a
  .container
    .row
      .col-lg-12
        h2#community Community mailing list
        p
          | Over 3000 Cucumber users are part of the daily discussions on our
          a<> href="https://groups.google.com/group/cukes" mailing list
          | It's a great place to get your questions answered, and to share your knowledge with others in the community.
            Please respect the
          a<> href="/posting-rules" posting rules.
    .row
      .col-lg-12
        h2#gitter Community Chat (Gitter)
        p
          | For quick help, you can try the
          a<> href="https://gitter.im/cucumber/chat" cucumber/chat
          | room hosted at Gitter.
      .col-lg-12
        h2#irc Community Chat (IRC)
        p
          | If you're old school you can try the
          a<> href="irc://irc.freenode.net/cucumber" #cucumber
          | IRC channel on freenode.net
    .row
      .col-lg-12
        h2#premium Premium Support
        p
          | When you want guaranteed accesss to prompt, expert help, you need premium support.
    .row.text-center.hidden-xs
      a.btn.btn-lg.btn-primary href="/CucumberPaidSupportPlans.pdf"  Download our premium support prices
    .row.text-center.visible-xs
      .jumbotron
        | Download our
        a href="/CucumberPaidSupportPlans.pdf" premium support prices


---
---
- samples = []
- for showcase_page in site.showcases
  - showcase = showcase_page.showcase
  - next if showcase.category.nil?
  - sample = {}
  - samples << sample
  - sample[:id] = showcase.module_path
  - sample[:name] = showcase.name
  - sample[:description] = showcase.description.nil? ? "" : showcase.description
  - sample[:html_url] = "#{site.base_url}#{showcase_page.output_path}"
  - sample[:category] = showcase.category.id
  - unless showcase.changes.nil?
    - sample[:last_updated] = showcase.changes.first.date
  - unless showcase.api_usage.nil?
    - sample[:usage] = []
    - for usage in showcase.api_usage.each_key
      - sample[:usage] << usage
  - unless showcase.contributors.nil?
    - sample[:authors] = []
    - for c in site.identities.unique_by_emails(showcase.contributors)
      - sample[:authors] << {:name => c.name, :avatar => c.avatar_url(25)}

=JSON.pretty_generate samples


meta charset="utf-8" /
meta content="IE=edge" http-equiv="X-UA-Compatible" /
meta content="width=device-width, initial-scale=1" name="viewport" /
meta content="cucumber, gherkin, testing, bdd, tdd, atdd, sbe, specification by example, requirements" name="keywords" /
meta content=(site['description']) name="description" /
meta content=(site['author']) name="author" /
meta content=(site['copyright']) name="copyright" /
link href=(site['url'] + '/feed.xml') rel="alternate" title=(site['name']) type="application/rss+xml" /

title
  - if title == "Cucumber"
    = title
  - else
    = title
    | ·
    | Cucumber

link href="/images/favicon.png" rel="icon" type="image/png" /
== css :main, media: 'screen'

Add swiftype meta tag for title

meta charset="utf-8" /
meta content="IE=edge" http-equiv="X-UA-Compatible" /
meta content="width=device-width, initial-scale=1" name="viewport" /
meta content="cucumber, gherkin, testing, bdd, tdd, atdd, sbe, specification by example, requirements" name="keywords" /
meta content=(site['description']) name="description" /
meta content=(site['author']) name="author" /
meta content=(site['copyright']) name="copyright" /
link href=(site['url'] + '/feed.xml') rel="alternate" title=(site['name']) type="application/rss+xml" /

title
  - if title == "Cucumber"
    = title
  - else
    = title
    | ·
    | Cucumber

meta property="st:title" content="#{title}"

link href="/images/favicon.png" rel="icon" type="image/png" /
== css :main, media: 'screen'


doctype html
html lang = "en"
  head
    title="#{item[:title]} - #{@config[:title]}"
    link href = "https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel = "stylesheet"
    script src = "https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"
    meta name = "viewport" content = "width=device-width, initial-scale=1.0"
    link rel="alternate" type="application/atom+xml" title=@config[:title] href="#{@config[:base_url]}/feed.xml"
  body
    .container
      header.row
        h1.col-md-6.col-md-offset-3: a href = "/" =@config[:title]
      nav.row
        ul.nav.nav-tabs.col-md-6.col-md-offset-3
          li: a href = "/" Home
          li: a href = "/download" Download
          li: a href = "/doc" Documentation
          li: a href = "/support" Support/Community
          li: a href = "/dev" Develop
      section.row
        div.col-md-6.col-md-offset-3
          == render "partials/donations"
      section.row
        div.col-md-6.col-md-offset-3
          h2=item[:title]
          == yield
      footer.row
        div.col-md-6.col-md-offset-3: Copyright © 2009-2013 Nolan Darilek.
    == render "partials/analytics"

Remove unnecessary divs from template.

doctype html
html lang = "en"
  head
    title="#{item[:title]} - #{@config[:title]}"
    link href = "https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel = "stylesheet"
    script src = "https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"
    meta name = "viewport" content = "width=device-width, initial-scale=1.0"
    link rel="alternate" type="application/atom+xml" title=@config[:title] href="#{@config[:base_url]}/feed.xml"
  body
    .container
      header.row
        h1.col-md-6.col-md-offset-3: a href = "/" =@config[:title]
      nav.row
        ul.nav.nav-tabs.col-md-6.col-md-offset-3
          li: a href = "/" Home
          li: a href = "/download" Download
          li: a href = "/doc" Documentation
          li: a href = "/support" Support/Community
          li: a href = "/dev" Develop
      section.row
        .col-md-6.col-md-offset-3
          == render "partials/donations"
      section.row
        .col-md-6.col-md-offset-3
          h2=item[:title]
          == yield
      footer.row
        .col-md-6.col-md-offset-3: Copyright © 2009-2013 Nolan Darilek.
    == render "partials/analytics"


- content_for :title, "Payment Info: #{@user.display_name}"

- content_for :page_content do
  .user-payments-content.row
    .large-12.columns
      h3 Payments here

- if request.xhr?
  = yield :page_content
- else
  = render template: 'users/edit'


- add_breadcrumb :new
= page_header
= simple_form_for [current_course, @group] do |f|
  = f.input :name

  = f.association :course_users, collection: current_course.course_users - [current_course_user]

  = f.button :submit

Sort course user dropdown in group creation page by name.

- add_breadcrumb :new
= page_header
= simple_form_for [current_course, @group] do |f|
  = f.input :name

  = f.association :course_users, collection: current_course.course_users.order_alphabetically - [current_course_user]

  = f.button :submit


---
layout: lecture
title: Views
---

section.center data-background="#000"
  h1.white Views

section.center data-background="#000"
  h1.white Presentation

section.center data-background="#000"
  h1.white The client side of the street

section.center data-background="#000"
  h1.white Response is HTML

section.center data-background="#000"
  h1.white Response is generated from templates

section.center data-background="#000"
  h1.white ActionController::Base#render

section.center
  h1 text, html, json, xml

section.center
  h1 render nothing: true

section.center data-background="#000"
  h1.white render with :inline

section.center data-background="#000"
  h1.white Conventions

section.center data-background="#000"
  h1.white Rendering by default

section.center data-background="#000"
  h1.white Layouts

section.center data-background="#000"
  h1.white Partials

section.center
  img.inline src="/images/hackman.png"


#header-mid
  #title-mid
    | User Registration
  .clear

  #content
    #box[style="padding-top: 50px;"]
      = simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
        = f.error_notification
        .form-inputs
          = f.input :email, required: true, autofocus: true
          br
          = f.input :first_name, required: true
          br
          = f.input :last_name, required: true
          br
          = f.input :password, required: true, hint: ("#{@minimum_password_length} characters minimum" if @validatable)
          br
          = f.input :password_confirmation, required: true
        .form-actions
          br
          = f.button :submit, "Sign up", :class => "button2"
          br
    == render "devise/shared/links"
    =render "layouts/footer"

Tweak -- add hint to password confirmation as well.

#header-mid
  #title-mid
    | User Registration
  .clear

  #content
    #box[style="padding-top: 50px;"]
      = simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
        = f.error_notification
        .form-inputs
          = f.input :email, required: true, autofocus: true
          br
          = f.input :first_name, required: true
          br
          = f.input :last_name, required: true
          br
          = f.input :password, required: true, hint: ("#{@minimum_password_length} characters minimum" if @validatable)
          br
          = f.input :password_confirmation, required: true, hint: ("#{@minimum_password_length} characters minimum" if @validatable)
        .form-actions
          br
          = f.button :submit, "Sign up", :class => "button2"
          br
    == render "devise/shared/links"
    =render "layouts/footer"


Create view form confirm_bank_account notification

|Howdy, #{user.display_name}!
br
br
|It's about time to confirm the bank account you inserted on #{Configuration[:company_name]} days ago.
br
br
|Go to #{link_to neighborly_balanced.new_confirmation_path, neighborly_balanced.new_confirmation_path} and finish the process.
br
br
|High fives,
br
|The #{Configuration[:company_name]} Team


h1 #{@changeset.title}
dl.dl-horizontal
  dt Changed
  dd = @changeset.created_at.to_s(:long)
  dt Person
  dd = link_to @changeset.person.name, @changeset.person
  dt Action
  dd = @changeset.action
  dt Scope
  dd = @changeset.scope
  dt Modifier
  dd
    - if @changeset.modifier?
      = link_to @changeset.modifier.name, @changeset.modifier

h3 Before
code = @changeset.original

h3 After
code = @changeset.modified

h2 Sync Logs
- @changeset.change_syncs.each do |change_sync|
  h3 = change_sync.syncinator
  - if change_sync.sync_logs.empty?
    .alert.alert-info = fa_icon 'info-circle', text: 'Unsynced'
  - else
    table.table
      tr
        th Started
        th Status
        th Action
        th Message
      - change_sync.sync_logs.each do |sync_log|
        tr
          td = sync_log.started_at.to_s(:short)
          td
            span class=sync_log.status_class title=sync_log.finished_at.try(:to_s, :long) data-toggle="tooltip"
              = fa_icon sync_log.icon, text: sync_log.status
          td = sync_log.action
          td
            - if sync_log.message?
              code = sync_log.message

Set HTML id attribute for sync_logs.

h1 #{@changeset.title}
dl.dl-horizontal
  dt Changed
  dd = @changeset.created_at.to_s(:long)
  dt Person
  dd = link_to @changeset.person.name, @changeset.person
  dt Action
  dd = @changeset.action
  dt Scope
  dd = @changeset.scope
  dt Modifier
  dd
    - if @changeset.modifier?
      = link_to @changeset.modifier.name, @changeset.modifier

h3 Before
code = @changeset.original

h3 After
code = @changeset.modified

h2 Sync Logs
- @changeset.change_syncs.each do |change_sync|
  h3 = change_sync.syncinator
  - if change_sync.sync_logs.empty?
    .alert.alert-info = fa_icon 'info-circle', text: 'Unsynced'
  - else
    table.table
      tr
        th Started
        th Status
        th Action
        th Message
      - change_sync.sync_logs.each do |sync_log|
        tr id=dom_id(change_sync)
          td = sync_log.started_at.to_s(:short)
          td
            span class=sync_log.status_class title=sync_log.finished_at.try(:to_s, :long) data-toggle="tooltip"
              = fa_icon sync_log.icon, text: sync_log.status
          td = sync_log.action
          td
            - if sync_log.message?
              code = sync_log.message


.row
  .col-xs-12
    h1
      | Listing users

    table.table.datatable
      thead
        tr
          th ID
          th Name
          th Created at
          th Admin
          th Actions

      tbody
        - users.each do |user|
          tr
            td = user.id
            td = user.name
            td = user.created_at
            td = user.admin_label
            td
              = link_to 'Edit skills', admin_user_skills_path(user), class: 'btn btn-primary'
              = user.toggle_admin_btn

Add row 'Paused' to Users table

.row
  .col-xs-12
    h1
      | Listing users

    table.table.datatable
      thead
        tr
          th ID
          th Name
          th Created at
          th Admin
          th Paused
          th Actions

      tbody
        - users.each do |user|
          tr
            td = user.id
            td = user.name
            td = user.created_at
            td = user.admin_label
            td
              = form_tag toggle_paused_user_path(user)
                input.project-switch type="checkbox" checked=("checked" unless user.paused) id="user-#{user.id}"
                label for="user-#{user.id}"
            td
              = link_to 'Edit skills', admin_user_skills_path(user), class: 'btn btn-primary'
              = user.toggle_admin_btn


Add layout for devise to make the admin ui sign in to work

doctype html
html
  head
    title Halloped
    = stylesheet_link_tag "application"
    = javascript_include_tag "application"
    = csrf_meta_tags
    meta(http-equiv='Content-Type' content='text/html; charset=UTF-8')
  body(data-env=Rails.env)
    #wrapper
      div#header
        #header-content
          .logo
          .headline
            | Halloped.fi Administration
          / Visible when user has logged in
      div#content
        div#page-content
          = yield

    div#footer
      p Copyright 2012 Halloped.fi

  div#modal-wrap


.table_content
  table.table.table-striped
    thead
      th= t('.table.project')
      th= t('.table.subscription_date')
      th= t('.table.status')
      th
    - subscriptions.each do |subscription|
        tr[id="subscription_#{subscription.id}"]
          td.project_name
            = link_to subscription.project.name, subscription.project, class: 'link_project'
          td.date = I18n.l(subscription.created_at.to_date)
          td.status = I18n.t(subscription.status, scope: [:activerecord, :attributes, :subscription, :statuses])
          td.cancel
            - unless subscription.canceled?
              = simple_form_for subscription, url: subscription_cancel_path, method: :post do |form|
                = form.input :id, as: :hidden, value: subscription.id
                = form.button :submit, t('.form.submit.cancel'), class: 'bg-red-error'


.uk-container.uk-container-center
  .uk-grid
    .uk-width-2-3
      .summary-list-item.uk-panel.uk-panel-box.uk-margin-top
        p.uk-text-center.uk-text-large
          | 認証エラーが発生しました


doctype html
html[lang="en"]
head
  css:
    body { margin: 20px }
    .content {
      background-color: #ddd;
      padding: 20px
    }
    p { font-family: serif; font-size: 16px }
body
  div.content
    = yield

Allow passing container width on example embed page

doctype html
html[lang="en"]
head
  css:
    body { margin: 20px }
    .content {
      background-color: #ddd;
      padding: 20px;
      width: #{params[:width] || 960}px;
    }
    p { font-family: serif; font-size: 16px }
body
  div.content
    = yield


.row
  .col-lg-6
    h1 Add email information

    /= render 'shared/errors_messages', resource: @user

    = form_tag register_path, method: :post do
      .form-group
        = label_tag 'Email'
        = text_field_tag 'auth_hash[info][email]', :email, class: 'form-control'

      p= submit_tag 'Add', class: 'btn btn-primary'


.row
  .col-xs-12
    .jumbotron
      h1 Reminders app
      p Welcome! You can find and configure reminders here! enjoy!

    .panel.panel-success
      .panel-heading
        h3.panel-title Your skills
      .panel-body
        | Please mark your "skills" - so you can be assigned to check some of the reminders:
        = link_to ' go to Skills page.', skills_path

    .panel.panel-primary
      .panel-heading
        h3.panel-title Info
      .panel-body
        | If you think there is something wrong, please ping us on reminders-related channel on Slack.

Add panel for changing pausing to root view

.row
  .col-xs-12
    .jumbotron
      h1 Reminders app
      p Welcome! You can find and configure reminders here! enjoy!

    .panel.panel-success
      .panel-heading
        h3.panel-title Your skills
      .panel-body
        | Please mark your "skills" - so you can be assigned to check some of the reminders:
        = link_to ' go to Skills page.', skills_path

    .panel.panel-success
      .panel-heading
        h3.panel-title Your availability
      .panel-body
        | Please, mark yourself as paused if you will not be available for reminders.
        strong
          |  At the moment you are #{current_user.decorate.paused_as_string}
        = link_to ' Click here to change it.',
                  toggle_paused_by_user_user_path(id: current_user.id),
                  method: :post

    .panel.panel-primary
      .panel-heading
        h3.panel-title Info
      .panel-body
        | If you think there is something wrong, please ping us on reminders-related channel on Slack.


- content_for(:title, 'Getting started')

h1 Getting started
h2 1. Install the recorder

= render partial: 'docs/script_install_and_other'

markdown:

  ## 2. Record

  Go to your terminal and run the following command:

      asciinema rec

  New shell will be spawned and everything you do in it will get recorded.
  When you're finished simply exit the shell either by typing `exit`
  or hitting `<C-d>`.

  See [usage instructions](#{docs_path(:usage)}) to learn about all commands and options.

  ## 3. Create your profile (optional)

  If you want your recordings to be assigned to your asciinema profile run the
  following command:

      asciinema auth

  If you skip this step now, you can run the above command later and all
  previously recorded asciicasts will automatically get assigned to your
  profile.

  NOTE: To be able to edit/delete your recordings you have to assign them to
  your profile.

Use <kbd> for key combo

- content_for(:title, 'Getting started')

h1 Getting started
h2 1. Install the recorder

= render partial: 'docs/script_install_and_other'

markdown:

  ## 2. Record

  Go to your terminal and run the following command:

      asciinema rec

  New shell will be spawned and everything you do in it will get recorded.
  When you're ready to finish simply exit the shell either by typing `exit` or
  hitting <kbd>Ctrl-D</kdb>.

  See [usage instructions](#{docs_path(:usage)}) to learn about all commands and options.

  ## 3. Create your profile (optional)

  If you want your recordings to be assigned to your asciinema profile run the
  following command:

      asciinema auth

  If you skip this step now, you can run the above command later and all
  previously recorded asciicasts will automatically get assigned to your
  profile.

  NOTE: To be able to edit/delete your recordings you have to assign them to
  your profile.


Add demo article to show syntax and examples

---
title: Demo Article
tags: Deodorant
disqus_id: demo-article
img: diy-deoderant-long.jpg
published: false
---

p This is a demo article. It shows the syntax to insert images, create links, make bold words and more.

p Let's start with a simple image.  The first parameter is the function name: "blog_img".  Next, you put the name of the image file (which must be in the "images" folder).  Finally, you put a description for the image.  This will appear as the "alt" attribute of the image in the final HTML.  It's important for SEO.

= blog_img "compare-3-jar-deoderants-primal-pit-paste-naturally-sourced-schmidt's.jpg", "my alt attribute text"

h2 Links

p Another helpful feature is creating links.  You can do this by wrapping the information in a special syntax with braces and a pound character.  Here's an example of a link to an article about the #{ link_to "alt attribute's relevance to SEO", "https://econsultancy.com/blog/63845-the-basics-of-using-alt-text-for-seo" }.

p That was a link to a random page on the internet.  If you wanted to link to somewhere within this site, you have a couple options.

p Here is a link to #{ link_to "Schmidt's Lavender and Sage product page", get_product_url(data.products["Schmidt's Lavender & Sage"]) }

p Here is a link to #{ link_to "Schmidt's Lavender and Sage affiliate link", data.products["Schmidt's Lavender & Sage"].affiliate_link }

p Here is a link to #{ link_to "an article on this site", get_post_url("Our review of the best tub deoderants") }

h2 Site Map

p To see every page that is on the website, you can browse the #{ link_to "sitemap", "/__middleman/sitemap/" }

h2 Font styles

p Here is how you can make words bold or italic:  More text with some <strong> words in bold</strong>.  And other <em> words in italic </em>

h2 Markdown

p Up until now we have been using "slim" syntax.  It has a "p" or other tag at the beginning of each line.  Another option is markdown.  It makes some things easier but it also gives you less control of appearance.  I just put it here for the sake of completeness.  Slim is probably a better option.

markdown:
  Here is a simple markdown example: Use **bold** text or *italics*.

  Here is a list using markdown:

    * First item
    * second item


head
  meta charset='utf-8'
  title = page_title
  meta name='description' content='#{page_description}'
  meta name='keywords' content='#{page_keywords}'
  meta name='author' content=''
  meta http-equiv='X-UA-Compatible' content='IE=edge'
  meta content='on' http-equiv='cleartype'
  meta content='True' name='HandheldFriendly'
  meta content='320' name='MobileOptimized'
  meta content='initial-scale=1, user-scalable=yes, width=device-width' name='viewport'
  link rel='shortcut icon' href='#{image_path('favicon.png')}'
  = stylesheet_link_tag 'application.css', media: 'all'
  /[if lt IE 9]
    = javascript_include_tag 'ie-lt-9'
  = yield_content :head

Add html5shiv polyfill using cdn. Add Modernizr development version using CDN. Adding comments to explain that the user needs to build its own version for production.

head
  meta charset='utf-8'
  title = page_title
  meta name='description' content='#{page_description}'
  meta name='keywords' content='#{page_keywords}'
  meta name='author' content=''
  meta http-equiv='X-UA-Compatible' content='IE=edge'
  meta content='on' http-equiv='cleartype'
  meta content='True' name='HandheldFriendly'
  meta content='320' name='MobileOptimized'
  meta content='initial-scale=1, user-scalable=yes, width=device-width' name='viewport'
  link rel='shortcut icon' href='#{image_path('favicon.png')}'
  = stylesheet_link_tag 'application.css', media: 'all'
  /[if lt IE 9]
    = javascript_include_tag '//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7/html5shiv.min.js'
  / -------------------------------------
  / Modernizr - Development version
  / Use the Development version to develop with and learn from. Then, when you’re
  / ready for production, use the build tool below to pick only the tests you need.
  / -------------------------------------
  = javascript_include_tag '//cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.2/modernizr.js'
  = yield_content :head


= partial 'analytics'
= javascript_include_tag 'requirements'
= javascript_include_tag 'application'
/[if (gte IE 6)&(lte IE 8)]
  = javascript_include_tag 'ie-lte-8'

Load query 1 and 2 depending on the version of internet explorer. Updating internet explorer javascripts polyfill, added nwmatcher with selectivizr and respond.js. All using cdn.

= partial 'analytics'

<!--[if lt IE 9]><!-->
  = javascript_include_tag '//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'
<!--<![endif]-->
<!--[if gte IE 9]><!-->
  = javascript_include_tag 'jquery/dist/jquery'
<!--<![endif]-->

= javascript_include_tag 'requirements'
= javascript_include_tag 'application'

/[if lt IE 9]
  = javascript_include_tag '//cdnjs.cloudflare.com/ajax/libs/nwmatcher/1.2.5/nwmatcher.min.js'
  = javascript_include_tag '//cdnjs.cloudflare.com/ajax/libs/selectivizr/1.0.2/selectivizr-min.js'
  = javascript_include_tag '//cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.js'


// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:sky' as sky;

import 'package:sky/gestures.dart';
import 'package:sky/widgets.dart';

import 'icon.dart';

class IconButton extends StatelessComponent {
  const IconButton({ Key key, this.icon, this.onPressed, this.color }) : super(key: key);

  final String icon;
  final Color color;
  final GestureTapCallback onPressed;

  Widget build(BuildContext context) {
    Widget child = new Icon(type: icon, size: 24);
    if (color != null) {
      child = new ColorFilter(
        color: color,
        transferMode: sky.TransferMode.srcATop,
        child: child
      );
    }
    return new GestureDetector(
      onTap: onPressed,
      child: new Padding(
        child: child,
        padding: const EdgeDims.all(8.0))
    );
  }
}

Make it fast to draw color icons

// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:sky' as sky;

import 'package:sky/gestures.dart';
import 'package:sky/widgets.dart';

import 'icon.dart';

class IconButton extends StatelessComponent {
  const IconButton({
    Key key,
    this.icon,
    this.color,
    this.colorFilter,
    this.onPressed
  }) : super(key: key);

  final String icon;
  final IconThemeColor color;
  final sky.ColorFilter colorFilter;
  final GestureTapCallback onPressed;

  Widget build(BuildContext context) {
    return new GestureDetector(
      onTap: onPressed,
      child: new Padding(
        padding: const EdgeDims.all(8.0),
        child: new Icon(
          type: icon,
          size: 24,
          color: color,
          colorFilter: colorFilter
        )
      )
    );
  }
}


// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// or details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Test date formatting and parsing using locale data read via an http request
 * to a server.
 */

library date_time_format_http_request_test;

import 'dart:html';
import 'package:unittest/html_config.dart';
import 'package:unittest/unittest.dart';
import 'package:intl/date_symbol_data_http_request.dart';
import 'date_time_format_test_stub.dart';

main() {
  useHtmlConfiguration();
  var url = "http://localhost:${window.location.port}"
    "/root_dart/pkg/intl/lib/src/data/dates/";

   test("Initializing a locale that needs fallback", () {
     initializeDateFormatting("de_DE", url).then(expectAsync((_) => true));
   });

  runWith(smallSetOfLocales, url, initializeDateFormatting);
}

Fix url location for http test

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// or details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * Test date formatting and parsing using locale data read via an http request
 * to a server.
 */

library date_time_format_http_request_test;

import 'dart:html';
import 'package:unittest/html_config.dart';
import 'package:unittest/unittest.dart';
import 'package:intl/date_symbol_data_http_request.dart';
import 'date_time_format_test_stub.dart';

main() {
  useHtmlConfiguration();
  var url = "http://localhost:${window.location.port}"
    "/packages/intl/src/data/dates/";

   test("Initializing a locale that needs fallback", () {
     initializeDateFormatting("de_DE", url).then(expectAsync((_) => true));
   });

  runWith(smallSetOfLocales, url, initializeDateFormatting);
}


// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:sky' as sky;

/// Helper class to build a Paint DrawLooper that adds shadows to the Paint's
/// operation.
class ShadowDrawLooperBuilder {
  var builder_ = new sky.LayerDrawLooperBuilder();

  void addShadow(sky.Size offset, sky.Color color, double blur) {
    builder_.addLayerOnTop(
          new sky.DrawLooperLayerInfo()
            ..setPaintBits(PaintBits.all)
            ..setOffset(offset.toPoint())
            ..setColorMode(sky.TransferMode.srcMode),
          (sky.Paint layerPaint) {
        layerPaint.color = color;
        layerPaint.setMaskFilter(
          new sky.MaskFilter.blur(sky.BlurStyle.normal,
                                  blur,
                                  highQuality: true));
      });
  }

  sky.DrawLooper build() {
    builder_.addLayerOnTop(new sky.DrawLooperLayerInfo(), (_) {});
    return builder_.build();
  }
}

Fix crash in stocks2 app caused by unspecified PaintBits.

// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:sky' as sky;

/// Helper class to build a Paint DrawLooper that adds shadows to the Paint's
/// operation.
class ShadowDrawLooperBuilder {
  var builder_ = new sky.LayerDrawLooperBuilder();

  void addShadow(sky.Size offset, sky.Color color, double blur) {
    builder_.addLayerOnTop(
          new sky.DrawLooperLayerInfo()
            ..setPaintBits(sky.PaintBits.all)
            ..setOffset(offset.toPoint())
            ..setColorMode(sky.TransferMode.srcMode),
          (sky.Paint layerPaint) {
        layerPaint.color = color;
        layerPaint.setMaskFilter(
          new sky.MaskFilter.blur(sky.BlurStyle.normal,
                                  blur,
                                  highQuality: true));
      });
  }

  sky.DrawLooper build() {
    builder_.addLayerOnTop(new sky.DrawLooperLayerInfo(), (_) {});
    return builder_.build();
  }
}


library hello_world.index;

import "package:angular2/bootstrap.dart" show AngularEntrypoint, bootstrap;
import "package:angular2/angular2.dart"
    show Component, Directive, ElementRef, Injectable, Renderer;

@AngularEntrypoint("Hello World Entrypoint")
main() {
  bootstrap(HelloCmp);
}

@Injectable()
class GreetingService {
  String greeting = "hello";
}

@Directive(selector: "[red]")
class RedDec {
  RedDec(ElementRef el, Renderer renderer) {
    renderer.setElementStyle(el, "color", "red");
  }
}

@Component(
    selector: "hello-app",
    viewProviders: const [GreetingService],
    template:
        '''
{{greeting}} world!

           <button class="changeButton" (click)="changeGreeting()">change greeting</button>''',
    directives: const [RedDec])
class HelloCmp {
  String greeting;
  HelloCmp(GreetingService service) {
    this.greeting = service.greeting;
  }
  void changeGreeting() {
    this.greeting = "howdy";
  }
}

Fix runtime error in hello_world payload app

library hello_world.index;

import "package:angular2/bootstrap.dart" show AngularEntrypoint, bootstrap;
import "package:angular2/angular2.dart"
    show Component, Directive, ElementRef, Injectable, Renderer;

@AngularEntrypoint("Hello World Entrypoint")
main() {
  bootstrap(HelloCmp);
}

@Injectable()
class GreetingService {
  String greeting = "hello";
}

@Directive(selector: "[red]")
class RedDec {
  RedDec(ElementRef el, Renderer renderer) {
    renderer.setElementStyle(el.nativeElement, "color", "red");
  }
}

@Component(
    selector: "hello-app",
    viewProviders: const [GreetingService],
    template:
        '''
{{greeting}} world!

           <button class="changeButton" (click)="changeGreeting()">change greeting</button>''',
    directives: const [RedDec])
class HelloCmp {
  String greeting;
  HelloCmp(GreetingService service) {
    this.greeting = service.greeting;
  }
  void changeGreeting() {
    this.greeting = "howdy";
  }
}


library keys;

import 'package:ctrl_alt_foo/shortcut.dart';
import 'package:ctrl_alt_foo/key_event_x.dart';

class Keys {
  static List subscriptions = [];

  static void shortcuts(Map shortcuts) {
    shortcuts.forEach((key, callback) {
      key.
        split(new RegExp(r'\s*,\s*')).
        forEach((k)=> new ShortCut.fromString(k, callback));
    });
  }

  static onEnter(el, callback) {
    var s = KeyboardEventStreamX.onKeyDown(el).listen((e) {
      if (!e.isEnter) return;
      e.preventDefault();
      callback();
    });
    subscriptions.add(s);
  }

  static bool isEnter(event) => new KeyEventX(event).isEnter;

  static onDown(el, callback) {
    var s = KeyboardEventStreamX.onKeyDown(el).listen((e) {
      if (!e.isDown) return;
      e.preventDefault();
      callback();
    });
    subscriptions.add(s);
  }

  static onUp(el, callback) {
    var s = KeyboardEventStreamX.onKeyDown(el).listen((e) {
      if (!e.isUp) return;
      e.preventDefault();
      callback();
    });
    subscriptions.add(s);
  }

  static cancel() {
    ShortCut.removeAll();
    Keys.removeAll();
  }

  static removeAll() {
    while (Keys.subscriptions.length > 0) {
      Keys.subscriptions.removeLast().cancel();
    }
  }
}

Support a giant hack to store last keyCode

library keys;

import 'package:ctrl_alt_foo/shortcut.dart';
import 'package:ctrl_alt_foo/key_event_x.dart';

class Keys {
  static int _lastKeyCode;
  static set lastKeyCode(v) { _lastKeyCode = v; }
  static get lastKeyCode {
    print('Horrible hack. FIXME ASAP!!!!');
    return _lastKeyCode;
  }

  static List subscriptions = [];

  static void shortcuts(Map shortcuts) {
    shortcuts.forEach((key, callback) {
      key.
        split(new RegExp(r'\s*,\s*')).
        forEach((k)=> new ShortCut.fromString(k, callback));
    });
  }

  static onEnter(el, callback) {
    var s = KeyboardEventStreamX.onKeyDown(el).listen((e) {
      if (!e.isEnter) return;
      e.preventDefault();
      callback();
    });
    subscriptions.add(s);
  }

  static bool isEnter(event) => new KeyEventX(event).isEnter;

  static onDown(el, callback) {
    var s = KeyboardEventStreamX.onKeyDown(el).listen((e) {
      if (!e.isDown) return;
      e.preventDefault();
      callback();
    });
    subscriptions.add(s);
  }

  static onUp(el, callback) {
    var s = KeyboardEventStreamX.onKeyDown(el).listen((e) {
      if (!e.isUp) return;
      e.preventDefault();
      callback();
    });
    subscriptions.add(s);
  }

  static cancel() {
    ShortCut.removeAll();
    Keys.removeAll();
  }

  static removeAll() {
    while (Keys.subscriptions.length > 0) {
      Keys.subscriptions.removeLast().cancel();
    }
  }
}


// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import "dart:isolate";
import "package:unittest/unittest.dart";

Uri toDartDataUri(String source) {
  return Uri.parse("data:application/dart;charset=utf-8,"
      "${Uri.encodeComponent(source)}");
}

main() {
  test('Simple response', () {
    String source = """
import "dart:isolate";
main(List args, SendPort replyPort) {
  replyPort.send(42);
}
""";

    RawReceivePort receivePort;
    receivePort = new RawReceivePort(expectAsync((message) {
      expect(message, equals(42));
      receivePort.close();
    }));
    Isolate.spawnUri(toDartDataUri(source), [], receivePort.sendPort);
  });
}

Migrate a VM test off the ancient deprecated unittest package.

// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import "dart:isolate";

import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";

Uri toDartDataUri(String source) {
  return Uri.parse("data:application/dart;charset=utf-8,"
      "${Uri.encodeComponent(source)}");
}

main() {
  String source = """
import "dart:isolate";
main(List args, SendPort replyPort) {
replyPort.send(42);
}
""";

  RawReceivePort receivePort;
  asyncStart();
  receivePort = new RawReceivePort((message) {
    Expect.equals(message, 42);
    receivePort.close();
    asyncEnd();
  });
  Isolate.spawnUri(toDartDataUri(source), [], receivePort.sendPort);
}


@TestOn('browser')
library angular2.test.symbol_inspector.symbol_inspector_test;

import 'dart:mirrors';

import 'symbol_inspector.dart';
import 'simple_library.dart';

import 'package:test/test.dart';

main() {
  group('getSymbolsFromLibrary', () {
    test('should extract symbols', () {
      var simpleLib = reflectClass(A).owner as LibraryMirror;
      var symbols = getSymbolsFromLibrary(simpleLib);
      expect(symbols, [
        'A',
        'ClosureParam',
        'ClosureReturn',
        'ConsParamType',
        'FieldType',
        'Generic',
        'GetterType',
        'MethodReturnType',
        'ParamType',
        'SomeInterface',
        'StaticFieldType',
        'TypedefParam',
        'TypedefReturnType'
      ]);
    });
  });
  group('ng2libs', () {
    test('should be available via mirrors', () {
      expect(commonLib.uri.toString(), 'package:angular2/common.dart');
      expect(compilerLib.uri.toString(), 'package:angular2/compiler.dart');
      expect(coreLib.uri.toString(), 'package:angular2/core.dart');
      expect(instrumentationLib.uri.toString(),
          'package:angular2/instrumentation.dart');
      expect(platformBrowserLib.uri.toString(),
          'package:angular2/platform/browser.dart');
      expect(platformCommonLib.uri.toString(),
          'package:angular2/platform/common.dart');
    });
  });
}

Mark another test as not working with dart2js

@TestOn('browser && !js')
library angular2.test.symbol_inspector.symbol_inspector_test;

import 'dart:mirrors';

import 'symbol_inspector.dart';
import 'simple_library.dart';

import 'package:test/test.dart';

main() {
  group('getSymbolsFromLibrary', () {
    test('should extract symbols', () {
      var simpleLib = reflectClass(A).owner as LibraryMirror;
      var symbols = getSymbolsFromLibrary(simpleLib);
      expect(symbols, [
        'A',
        'ClosureParam',
        'ClosureReturn',
        'ConsParamType',
        'FieldType',
        'Generic',
        'GetterType',
        'MethodReturnType',
        'ParamType',
        'SomeInterface',
        'StaticFieldType',
        'TypedefParam',
        'TypedefReturnType'
      ]);
    });
  });
  group('ng2libs', () {
    test('should be available via mirrors', () {
      expect(commonLib.uri.toString(), 'package:angular2/common.dart');
      expect(compilerLib.uri.toString(), 'package:angular2/compiler.dart');
      expect(coreLib.uri.toString(), 'package:angular2/core.dart');
      expect(instrumentationLib.uri.toString(),
          'package:angular2/instrumentation.dart');
      expect(platformBrowserLib.uri.toString(),
          'package:angular2/platform/browser.dart');
      expect(platformCommonLib.uri.toString(),
          'package:angular2/platform/common.dart');
    });
  });
}


// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Test that different representations of the same string are all equal.

import "dart:convert";

import "package:expect/expect.dart";

main() {
  var base = "\u{10412}";
  var strings = [
    "\u{10412}",
    "𐐒",
    new String.fromCharCodes([0xd801, 0xdc12]),
    base[0] + base[1],
    "$base",
    "${base[0]}${base[1]}",
    "${base[0]}${base.substring(1)}",
    new String.fromCharCodes([0x10412]),
    ("a" + base).substring(1),
    (new StringBuffer()..writeCharCode(0xd801)
                       ..writeCharCode(0xdc12)).toString(),
    (new StringBuffer()..writeCharCode(0x10412)).toString(),
    JSON.decode('"\u{10412}"'),
    JSON.decode('{"\u{10412}":[]}').keys.first
  ];
  for (String string in strings) {
    Expect.equals(base.length, string.length);
    Expect.equals(base, string);
    Expect.equals(base.hashCode, string.hashCode);
    Expect.listEquals(base.codeUnits.toList(), string.codeUnits.toList());
  }
}

Fix test to not assume that JSON.decode returns dynamic.

// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Test that different representations of the same string are all equal.

import "dart:convert";

import "package:expect/expect.dart";

main() {
  var base = "\u{10412}";
  var strings = [
    "\u{10412}",
    "𐐒",
    new String.fromCharCodes([0xd801, 0xdc12]),
    base[0] + base[1],
    "$base",
    "${base[0]}${base[1]}",
    "${base[0]}${base.substring(1)}",
    new String.fromCharCodes([0x10412]),
    ("a" + base).substring(1),
    (new StringBuffer()..writeCharCode(0xd801)
                       ..writeCharCode(0xdc12)).toString(),
    (new StringBuffer()..writeCharCode(0x10412)).toString(),
    JSON.decode('"\u{10412}"'),
    (JSON.decode('{"\u{10412}":[]}') as Map).keys.first
  ];
  for (String string in strings) {
    Expect.equals(base.length, string.length);
    Expect.equals(base, string);
    Expect.equals(base.hashCode, string.hashCode);
    Expect.listEquals(base.codeUnits.toList(), string.codeUnits.toList());
  }
}


part of angular.mock;

@proxy
class MockWindow extends Mock implements Window {
  final history = new MockHistory();
  final location = new MockLocation();
  final document = new MockDocument();

  final onPopStateController = new dart_async.StreamController<PopStateEvent>();
  final onHashChangeController = new dart_async.StreamController<Event>();
  final onClickController = new dart_async.StreamController<MouseEvent>();

  dart_async.Stream<PopStateEvent> get onPopState => onPopStateController.stream;
  dart_async.Stream<Event> get onHashChange => onHashChangeController.stream;
  dart_async.Stream<Event> get onClick => onClickController.stream;
  dart_async.Future<num> get animationFrame => animationFrameCompleter.future;

  executeAnimationFrame([num time=0.0]) {
    var last = animationFrameCompleter;
    animationFrameCompleter = new dart_async.Completer<num>();
    last.complete(time);
  }

  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

@proxy
class MockHistory extends Mock implements History {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

@proxy
class MockLocation extends Mock implements Location {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

@proxy
class MockDocument extends Mock implements HtmlDocument {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

Fix unitialized variable in MockWindow.

part of angular.mock;

@proxy
class MockWindow extends Mock implements Window {
  final history = new MockHistory();
  final location = new MockLocation();
  final document = new MockDocument();

  final onPopStateController = new dart_async.StreamController<PopStateEvent>();
  final onHashChangeController = new dart_async.StreamController<Event>();
  final onClickController = new dart_async.StreamController<MouseEvent>();

  var animationFrameCompleter = new dart_async.Completer<num>();

  dart_async.Stream<PopStateEvent> get onPopState => onPopStateController.stream;
  dart_async.Stream<Event> get onHashChange => onHashChangeController.stream;
  dart_async.Stream<Event> get onClick => onClickController.stream;
  dart_async.Future<num> get animationFrame => animationFrameCompleter.future;

  executeAnimationFrame([num time=0.0]) {
    var last = animationFrameCompleter;
    animationFrameCompleter = new dart_async.Completer<num>();
    last.complete(time);
  }

  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

@proxy
class MockHistory extends Mock implements History {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

@proxy
class MockLocation extends Mock implements Location {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

@proxy
class MockDocument extends Mock implements HtmlDocument {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}


// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'basic.dart';
import 'button_base.dart';
import 'ink_well.dart';
import 'material.dart';
import 'theme.dart';

// TODO(eseidel): This needs to change based on device size?
// http://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing
const double _kSize = 56.0;

class FloatingActionButton extends ButtonBase {

  FloatingActionButton({
    String key,
    this.child,
    Function onPressed
  }) : super(key: key);

  Widget child;
  Function onPressed;

  void syncFields(FloatingActionButton source) {
    super.syncFields(source);
    child = source.child;
    onPressed = source.onPressed;
  }

  Widget buildContent() {
    return new Material(
      color: Theme.of(this).accent[200],
      edge: MaterialEdge.circle,
      level: highlight ? 3 : 2,
      child: new ClipOval(
        child: new Listener(
          onGestureTap: (_) {
            if (onPressed != null)
              onPressed();
          },
          child: new Container(
            width: _kSize,
            height: _kSize,
            child: new InkWell(child: new Center(child: child))
          )
        )
      )
    );
  }

}

Make FloatingActionButton respect the onPressed ctor arg.

// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'basic.dart';
import 'button_base.dart';
import 'ink_well.dart';
import 'material.dart';
import 'theme.dart';

// TODO(eseidel): This needs to change based on device size?
// http://www.google.com/design/spec/layout/metrics-keylines.html#metrics-keylines-keylines-spacing
const double _kSize = 56.0;

class FloatingActionButton extends ButtonBase {

  FloatingActionButton({
    String key,
    this.child,
    this.onPressed
  }) : super(key: key);

  Widget child;
  Function onPressed;

  void syncFields(FloatingActionButton source) {
    super.syncFields(source);
    child = source.child;
    onPressed = source.onPressed;
  }

  Widget buildContent() {
    return new Material(
      color: Theme.of(this).accent[200],
      edge: MaterialEdge.circle,
      level: highlight ? 3 : 2,
      child: new ClipOval(
        child: new Listener(
          onGestureTap: (_) {
            if (onPressed != null)
              onPressed();
          },
          child: new Container(
            width: _kSize,
            height: _kSize,
            child: new InkWell(child: new Center(child: child))
          )
        )
      )
    );
  }

}


import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

import '../../features/activity/presentation/bloc/activity_bloc.dart';
import '../helpers/color_palette_helper.dart';

class ServerHeader extends StatelessWidget {
  final String serverName;
  final ActivityLoadingState state;

  const ServerHeader({
    Key key,
    @required this.serverName,
    this.state,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(
        left: 8,
        top: 8,
        bottom: 8,
      ),
      child: Row(
        children: <Widget>[
          Text(
            serverName,
            style: TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.w600,
              color: Theme.of(context).accentColor,
            ),
          ),
          if (state == ActivityLoadingState.inProgress)
            Padding(
              padding: const EdgeInsets.only(left: 4),
              child: SizedBox(
                height: 15,
                width: 15,
                child: CircularProgressIndicator(
                  strokeWidth: 2,
                ),
              ),
            ),
          if (state == ActivityLoadingState.failure)
            Padding(
              padding: const EdgeInsets.only(left: 4),
              child: FaIcon(
                FontAwesomeIcons.exclamationCircle,
                size: 15,
                color: TautulliColorPalette.not_white,
              ),
            ),
        ],
      ),
    );
  }
}

Adjust server header padding to match dropdowns.

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

import '../../features/activity/presentation/bloc/activity_bloc.dart';
import '../helpers/color_palette_helper.dart';

class ServerHeader extends StatelessWidget {
  final String serverName;
  final ActivityLoadingState state;

  const ServerHeader({
    Key key,
    @required this.serverName,
    this.state,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(
        left: 8,
        top: 8.2,
        bottom: 12.5,
      ),
      child: Row(
        children: <Widget>[
          Text(
            serverName,
            style: TextStyle(
              fontSize: 18,
              fontWeight: FontWeight.w600,
              color: Theme.of(context).accentColor,
            ),
          ),
          if (state == ActivityLoadingState.inProgress)
            Padding(
              padding: const EdgeInsets.only(left: 4),
              child: SizedBox(
                height: 15,
                width: 15,
                child: CircularProgressIndicator(
                  strokeWidth: 2,
                ),
              ),
            ),
          if (state == ActivityLoadingState.failure)
            Padding(
              padding: const EdgeInsets.only(left: 4),
              child: FaIcon(
                FontAwesomeIcons.exclamationCircle,
                size: 15,
                color: TautulliColorPalette.not_white,
              ),
            ),
        ],
      ),
    );
  }
}


part of irc.bot;

class DumbBot extends Bot {
  Client _client;
  List<String> channels = [];

  DumbBot(BotConfig config) {
    _client = new Client(config);
    _registerHandlers();
  }

  void _registerHandlers() {
    whenReady((ReadyEvent event) => channels.forEach((chan) => event.join(chan)));

    onMessage((MessageEvent event) => print("<${event.target}><${event.from}> ${event.message}"));
  }

  @override
  Client client() => _client;
}

Fix Dumb Bot for the new Event System (it was left out)

part of irc.bot;

class DumbBot extends Bot {
  Client _client;
  List<String> channels = [];

  DumbBot(BotConfig config) {
    _client = new Client(config);
    _registerHandlers();
  }

  void _registerHandlers() {
    register((ReadyEvent event) => channels.forEach((chan) => event.join(chan)));

    register((MessageEvent event) => print("<${event.target}><${event.from}> ${event.message}"));
  }

  @override
  Client client() => _client;
}


import 'package:unittest/unittest.dart';
import 'package:workmantrainer/textmarker.dart';

void main() {
  test('check initialisation of TextMarker Class works.', () {
    var tm = new TextMarker('some text',0,2,"CORRECT");
    expect(tm.targettext, 'some text');
    expect(tm.startposition,0);
    expect(tm.endposition,2);
    expect(tm.textState, 'CORRECT');
  });
  test('typedCorrectly returns correct span element.', () {
    var tm = new TextMarker('some text', 0, 2, "CORRECT");
    var span = tm.typedCorrectly();
    expect(span.text, 'so');
    expect(span.className, 'typedcorrect');
  });
}

Add tests for remaining span elements.

import 'package:unittest/unittest.dart';
import 'package:workmantrainer/textmarker.dart';

void main() {
  test('check initialisation of TextMarker Class works.', () {
    var tm = new TextMarker('some text',0,2,"CORRECT");
    expect(tm.targettext, 'some text');
    expect(tm.startposition,0);
    expect(tm.endposition,2);
    expect(tm.textState, 'CORRECT');
  });
  test('typedCorrectly returns correct span element.', () {
    var tm = new TextMarker('some text', 0, 2, "CORRECT");
    var span = tm.typedCorrectly();
    expect(span.text, 'so');
    expect(span.className, 'typedcorrect');
  });
  test('typedIncorrectly returns correct span element.', () {
    var tm = new TextMarker('some text', 0, 9, "INCORRECT");
    var span = tm.typedIncorrectly();
    expect(span.text, 'some text');
    expect(span.className, 'typedincorrect');
  });
  test('yetToBeTyped returns correct span element.', () {
    var tm = new TextMarker('some text', 0,1,'NOTTYPED');
    var span = tm.yetToBeTyped();
    expect(span.text, 's');
    expect(span.className, 'nottyped');
  });
}


// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import "package:expect/expect.dart";
import "dart:async";
import "dart:io";
import "dart:isolate";

void testPauseList() {
  var keepAlive = new ReceivePort();
  new Directory("").createTemp().then((d) {
    // Linux reads 2K at a time, so be sure to be >>.
    int total = 4 * 1024 + 1;
    for (int i = 0; i < total; i++) {
      new File("${d.path}/$i").createSync();
    }
    bool first = true;
    var subscription;
    int count = 0;
    subscription = d.list().listen((file) {
      if (first) {
        first = false;
        subscription.pause();
        Timer.run(() {
          for (int i = 0; i < total; i++) {
            new File("${d.path}/$i").deleteSync();
          }
          subscription.resume();
        });
      }
      count++;
    }, onDone: () {
      Expect.notEquals(total, count);
      keepAlive.close();
      d.delete().then((ignore) => keepAlive.close());
    });
  });
}

void main() {
  testPauseList();
}

Use directories with content, to avoid very large folder and flakyness.

// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import "package:expect/expect.dart";
import "dart:async";
import "dart:io";
import "dart:isolate";

void testPauseList() {
  var keepAlive = new ReceivePort();
  // TOTAL should be bigger the our directory listing buffer.
  const int TOTAL = 128;
  new Directory("").createTemp().then((d) {
    for (int i = 0; i < TOTAL; i++) {
      new Directory("${d.path}/$i").createSync();
      new File("${d.path}/$i/file").createSync();
    }
    bool first = true;
    var subscription;
    int count = 0;
    subscription = d.list(recursive: true).listen((file) {
      if (file is File) {
        if (first) {
          first = false;
          subscription.pause();
          Timer.run(() {
            for (int i = 0; i < TOTAL; i++) {
              new File("${d.path}/$i/file").deleteSync();
            }
            subscription.resume();
          });
        }
        count++;
      }
    }, onDone: () {
      Expect.notEquals(TOTAL, count);
      Expect.isTrue(count > 0);
      keepAlive.close();
      d.delete(recursive: true).then((ignore) => keepAlive.close());
    });
  });
}

void main() {
  testPauseList();
}


// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#library('XHRCrossOriginTest');
#import('../../lib/unittest/unittest.dart');
#import('../../lib/unittest/html_config.dart');
#import('dart:html');
#import('dart:json');

main() {
  useHtmlConfiguration();

  test('XHR Cross-domain', () {
    var xhr = new XMLHttpRequest();
    var url = "https://code.google.com/feeds/issues/p/dart/issues/full?alt=json";
    xhr.open('GET', url, true);
    var validate = expectAsync1((data) {
      expect(data, contains('feed'));
      expect(data['feed'], contains('entry'));
      expect(data is Map, isTrue);
    });
    xhr.on.readyStateChange.add((e) {
      guardAsync(() {
        if (xhr.readyState == XMLHttpRequest.DONE) {
          validate(JSON.parse(xhr.response));
        }
      });
    });
    xhr.send();
  });

  test('XHR.get Cross-domain', () {
    var url = "https://code.google.com/feeds/issues/p/dart/issues/full?alt=json";
    new XMLHttpRequest.get(url, expectAsync1((xhr) {
      var data = JSON.parse(xhr.response);
      expect(data, contains('feed'));
      expect(data['feed'], contains('entry'));
      expect(data is Map, isTrue);
    }));
  });
}

Fix missed spot for move of unittest from lib to pkg. TBR=rnystrom

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#library('XHRCrossOriginTest');
#import('../../pkg/unittest/unittest.dart');
#import('../../pkg/unittest/html_config.dart');
#import('dart:html');
#import('dart:json');

main() {
  useHtmlConfiguration();

  test('XHR Cross-domain', () {
    var xhr = new XMLHttpRequest();
    var url = "https://code.google.com/feeds/issues/p/dart/issues/full?alt=json";
    xhr.open('GET', url, true);
    var validate = expectAsync1((data) {
      expect(data, contains('feed'));
      expect(data['feed'], contains('entry'));
      expect(data is Map, isTrue);
    });
    xhr.on.readyStateChange.add((e) {
      guardAsync(() {
        if (xhr.readyState == XMLHttpRequest.DONE) {
          validate(JSON.parse(xhr.response));
        }
      });
    });
    xhr.send();
  });

  test('XHR.get Cross-domain', () {
    var url = "https://code.google.com/feeds/issues/p/dart/issues/full?alt=json";
    new XMLHttpRequest.get(url, expectAsync1((xhr) {
      var data = JSON.parse(xhr.response);
      expect(data, contains('feed'));
      expect(data['feed'], contains('entry'));
      expect(data is Map, isTrue);
    }));
  });
}


/* Bot Abstraction */
library irc.bot;

import 'package:irc/irc.dart';
import 'dart:async';
import 'dart:io';

part 'src/bot/dumbbot.dart';
part "src/bot/commandbot.dart";
part 'src/bot/base.dart';
part 'src/bot/logbot.dart';

Use single quote for part/import statements

/* Bot Abstraction */
library irc.bot;

import 'package:irc/irc.dart';
import 'dart:async';
import 'dart:io';

part 'src/bot/dumbbot.dart';
part 'src/bot/commandbot.dart';
part 'src/bot/base.dart';
part 'src/bot/logbot.dart';


import 'package:codemod/codemod.dart';

/// The latest version of riverpod that migrated code should be updated to
// TODO add a test that this version is up-to-date
const latestVersion = '1.0.0-dev.10';

/// Migrates the pubspec to the [latestVersion]
Stream<Patch> versionMigrationSuggestor(FileContext context) async* {
  final matches = RegExp(
          r'riverpod:\s+\^?([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?')
      .allMatches(context.sourceText);
  for (final m in matches) {
    yield Patch('riverpod: ^$latestVersion', m.start, m.end);
  }
}

Make migration update to 1.0.0

import 'package:codemod/codemod.dart';

/// The latest version of riverpod that migrated code should be updated to
// TODO add a test that this version is up-to-date
const latestVersion = '1.0.0';

/// Migrates the pubspec to the [latestVersion]
Stream<Patch> versionMigrationSuggestor(FileContext context) async* {
  final matches = RegExp(
          r'riverpod:\s+\^?([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?')
      .allMatches(context.sourceText);
  for (final m in matches) {
    yield Patch('riverpod: ^$latestVersion', m.start, m.end);
  }
}


import 'package:jael_web/jael_web.dart';
import 'package:jael_web/elements.dart';
part 'main.g.dart';

@Dsx(template: '''

Hello, Jael!

  Current time: {now}

''')
class Hello extends Component with _HelloJaelTemplate {
  DateTime get now => DateTime.now();
}

// Could also have been:
class Hello2 extends Component {
  DateTime get now => DateTime.now();

  @override
  DomNode render() {
    return div(c: [
      h1(c: [
        text('Hello, Jael!'),
      ]),
      i(c: [
        text('Current time: $now'),
      ]),
    ]);
  }
}

Use Jael in example 1

import 'package:jael_web/jael_web.dart';
import 'package:jael_web/elements.dart';
part 'main.g.dart';

@Jael(template: '''

Hello, Jael!

  Current time: {{now}}

''')
class Hello extends Component with _HelloJaelTemplate {
  DateTime get now => DateTime.now();
}

// Could also have been:
class Hello2 extends Component {
  DateTime get now => DateTime.now();

  @override
  DomNode render() {
    return div(c: [
      h1(c: [
        text('Hello, Jael!'),
      ]),
      i(c: [
        text('Current time: $now'),
      ]),
    ]);
  }
}


part of image;

/**
 * Apply a smoothing convolution filter to the [src] image.
 *
 * [w] is the weight of the current pixel being filtered.  If it's greater than
 * 1.0, it will make the image sharper.
 */
Image smooth(Image src, num w) {
  List<double> filter = [
    1.0, 1.0, 1.0,
    1.0, w,   1.0,
    1.0, 1.0, 1.0];

  return convolution(src, filter, w + 8, 0);
}

Fix a Dart 2 runtime failure

part of image;

/**
 * Apply a smoothing convolution filter to the [src] image.
 *
 * [w] is the weight of the current pixel being filtered.  If it's greater than
 * 1.0, it will make the image sharper.
 */
Image smooth(Image src, num w) {
  List<double> filter = [
    1.0, 1.0, 1.0,
    1.0, w.toDouble(),   1.0,
    1.0, 1.0, 1.0];

  return convolution(src, filter, w + 8, 0);
}


// Before blank line

// After blank line

/// This is my class.
class MyClass {
  /// This is my num field.
  num myNumField;

  /// This is my num getter.
  num get myNumGetter => 1;

  /// This is my num setter.
  set myNumSetter(num value) {}

  /// This is my class constructor.
  MyClass();

  /// This is my class named constructor.
  MyClass.myNamed();

  /// This is my void returning method.
  void myVoidReturningMethod() {}

  /// This is my string returning method.
  String myStringReturningMethod() {
    return "";
  }

  /// This is my method taking a string.
  void methodTakingString(String a) {}

  /// This is my method taking a function.
  void methodTakingFunction(int Function(String) myFunc) {}
}

void doSomeStuff() {
  var a = new MyClass();
  var b = new MyClass.myNamed();
  print(a.myNumField);
  print(a.myNumGetter);
  a.myNumSetter = 1;
  print(b.myStringReturningMethod());
  b.myVoidReturningMethod();
  b.methodTakingString("Hello");
  b.methodTakingFunction((s) => print(s));
}

Fix static error - Dart 2 symantics

// Before blank line

// After blank line

/// This is my class.
class MyClass {
  /// This is my num field.
  num myNumField;

  /// This is my num getter.
  num get myNumGetter => 1;

  /// This is my num setter.
  set myNumSetter(num value) {}

  /// This is my class constructor.
  MyClass();

  /// This is my class named constructor.
  MyClass.myNamed();

  /// This is my void returning method.
  void myVoidReturningMethod() {}

  /// This is my string returning method.
  String myStringReturningMethod() {
    return "";
  }

  /// This is my method taking a string.
  void methodTakingString(String a) {}

  /// This is my method taking a function.
  void methodTakingFunction(void Function(String) myFunc) {}
}

void doSomeStuff() {
  var a = new MyClass();
  var b = new MyClass.myNamed();
  print(a.myNumField);
  print(a.myNumGetter);
  a.myNumSetter = 1;
  print(b.myStringReturningMethod());
  b.myVoidReturningMethod();
  b.methodTakingString("Hello");
  b.methodTakingFunction((s) => print(s));
}


// Copyright (c) 2016, <your name>. All rights reserved. Use of this source code
// is governed by a BSD-style license that can be found in the LICENSE file.

library markov.example;

import 'dart:convert';
import 'dart:io';

import 'package:markov/markov.dart';

main() async {
  print("Provide source text by stdin. For best result, provide a large number "
      "of tweets, one per line.\n\n"
      "  \$ dart stdin_example.dart < tweets.txt\n"
      "  Here's your generated tweet.");

  // List<String> lines = await stdin
  //     .transform(new Utf8Decoder())
  //     .transform(new LineSplitter())
  //     .fold([], (List prev, next) {
  //   prev.add(next);
  //   return prev;
  // });
  //
  // // Chunked conversion is currently unimplemented, otherwise we could just
  // // use another `transform()` above.
  // MarkovChain chain = new MarkovConverter(2).convert(lines);

  // Take POSIX standard input stream (or any other byte
  // stream) and use it as source text.
  var chain = await stdin
      .transform(new Utf8Decoder())
      .transform(new LineSplitter())
      .pipe(new MarkovChainGenerator(2));

  // Take just one tweet worth of generated content (terminated by a newline).
  List<Token> tokens =
      chain.generate().takeWhile((token) => token.string != "\n").toList();

  print(format(tokens));
}

Remove dead commented out code.

// Copyright (c) 2016, <your name>. All rights reserved. Use of this source code
// is governed by a BSD-style license that can be found in the LICENSE file.

library markov.example;

import 'dart:convert';
import 'dart:io';

import 'package:markov/markov.dart';

main() async {
  print("Provide source text by stdin. For best result, provide a large number "
      "of tweets, one per line.\n\n"
      "  \$ dart stdin_example.dart < tweets.txt\n"
      "  Here's your generated tweet.");

  // Take POSIX standard input stream (or any other byte
  // stream) and use it as source text.
  var chain = await stdin
      .transform(new Utf8Decoder())
      .transform(new LineSplitter())
      .pipe(new MarkovChainGenerator(2));

  // Take just one tweet worth of generated content (terminated by a newline).
  List<Token> tokens =
      chain.generate().takeWhile((token) => token.string != "\n").toList();

  print(format(tokens));
}


// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';

// This library contains a member loadLibrary.
// Check that we shadow this member.
import "deferred_closurize_load_library_lib.dart" deferred as lib;

void main() {
  var x = lib.loadLibrary;
  asyncStart();
  x().then((_) {
    Expect.isTrue(lib.trueVar);
    asyncEnd();
  });
}

Remove spurious comment in test.

// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:expect/expect.dart';
import 'package:async_helper/async_helper.dart';

import "deferred_closurize_load_library_lib.dart" deferred as lib;

void main() {
  var x = lib.loadLibrary;
  asyncStart();
  x().then((_) {
    Expect.isTrue(lib.trueVar);
    asyncEnd();
  });
}


import 'package:flutter/material.dart';

void main() => runApp(MyBrokenApp());

class MyBrokenApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: MyBrokenHomePage(),
    );
  }
}

class MyBrokenHomePage extends StatelessWidget {
  MyBrokenHomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    _throwAnException();
    return Text("test");
  }

  void _throwAnException() {
    throw Exception("Oops");
  }
}

Fix a race in structured errors tests

import 'dart:async';

import 'package:flutter/material.dart';

void main() => runApp(MyBrokenApp());

class MyBrokenApp extends StatefulWidget {
  @override
  _MyBrokenAppState createState() => _MyBrokenAppState();
}

class _MyBrokenAppState extends State<MyBrokenApp> {
  bool shouldBeBroken = false;

  @override
  void initState() {
    super.initState();

    // Enabling structured errors has a race - we can't enable it until the app
    // is running, but if we throw an exception immediately, it may occur before
    // structured errors was enabled. So, this app waits 2 seconds before switching
    // to a widget that throws, to allow any startup things like this to occur first.
    new Timer(
      const Duration(seconds: 2),
      () => setState(() => shouldBeBroken = true),
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: shouldBeBroken ? MyBrokenHomePage() : MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Text("test");
  }
}

class MyBrokenHomePage extends StatelessWidget {
  MyBrokenHomePage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    _throwAnException();
    return Text("test");
  }

  void _throwAnException() {
    throw Exception("Oops");
  }
}


enum HeadPhoneStrategy { none, pauseOnUnplug, pauseOnUnplugPlayOnPlug }

String describeHeadPhoneStrategy(HeadPhoneStrategy strategy) {
  switch (strategy) {
    case HeadPhoneStrategy.none:
      return "none";
    case HeadPhoneStrategy.pauseOnUnplug:
      return "pauseOnUnplug";
    case HeadPhoneStrategy.pauseOnUnplugPlayOnPlug:
      return "pauseOnUnplugPlayOnPlug";
  }
  return null;
}

class AudioFocusStrategy {
  final bool request;
  final bool resumeAfterInterruption;
  final bool resumeOthersPlayersAfterDone;

  /***
   * Don't request focus
   */
  AudioFocusStrategy.none()
      : this.request = false,
        this.resumeAfterInterruption = false,
        this.resumeOthersPlayersAfterDone = false;

  /***
   * Request focus
   *
   * resumeAfterInterruption : When other app request focus (phone call, other player like spotify play), pause the AssetMediaPlayer
   * resumeOthersPlayersAfterDone : When this player finish to play, tell others native players (like spotify), to resume
   */
  const AudioFocusStrategy.request(
      {this.resumeAfterInterruption = false,
      this.resumeOthersPlayersAfterDone = false})
      : this.request = true;
}

Map<String, dynamic> describeAudioFocusStrategy(AudioFocusStrategy strategy) {
  return {
    "request": strategy.request,
    "resumeAfterInterruption": strategy.resumeAfterInterruption,
    "resumeOthersPlayersAfterDone": strategy.resumeOthersPlayersAfterDone,
  };
}

Correct pub.dev static analysis issues

enum HeadPhoneStrategy { none, pauseOnUnplug, pauseOnUnplugPlayOnPlug }

String describeHeadPhoneStrategy(HeadPhoneStrategy strategy) {
  switch (strategy) {
    case HeadPhoneStrategy.none:
      return "none";
    case HeadPhoneStrategy.pauseOnUnplug:
      return "pauseOnUnplug";
    case HeadPhoneStrategy.pauseOnUnplugPlayOnPlug:
      return "pauseOnUnplugPlayOnPlug";
  }
  return null;
}

class AudioFocusStrategy {
  final bool request;
  final bool resumeAfterInterruption;
  final bool resumeOthersPlayersAfterDone;

  /// Don't request focus
  AudioFocusStrategy.none()
      : this.request = false,
        this.resumeAfterInterruption = false,
        this.resumeOthersPlayersAfterDone = false;

  /// Request focus
  ///
  /// resumeAfterInterruption : When other app request focus (phone call, other player like spotify play), pause the AssetMediaPlayer
  ///
  /// resumeOthersPlayersAfterDone : When this player finish to play, tell others native players (like spotify), to resume
  const AudioFocusStrategy.request(
      {this.resumeAfterInterruption = false,
      this.resumeOthersPlayersAfterDone = false})
      : this.request = true;
}

Map<String, dynamic> describeAudioFocusStrategy(AudioFocusStrategy strategy) {
  return {
    "request": strategy.request,
    "resumeAfterInterruption": strategy.resumeAfterInterruption,
    "resumeOthersPlayersAfterDone": strategy.resumeOthersPlayersAfterDone,
  };
}


library ddrive.src.commands.init;

import 'package:unscripted/unscripted.dart';
import 'package:googleapis/drive/v2.dart' as drive;
import 'package:path/path.dart' as path;

import '../context.dart' as context;

class InitCommand {

  @SubCommand(help: 'Gets the quota information about the current user')
  init({ @Option(help: 'The root directory for Google Drive. Defaults to your current directory') String driveHome }) async {
    String p = driveHome == null || driveHome.isEmpty ? path.current : driveHome; //path ? path : path.current;
    bool firstTime = ! await context.credentialsExist(p);
    context.askForAuthorization(p);
  }
}

Refactor and clean up code

library ddrive.src.commands.init;

import 'package:unscripted/unscripted.dart';
import 'package:googleapis/drive/v2.dart' as drive;
import 'package:path/path.dart' as path;

import '../context.dart' as context;

class InitCommand {

  @SubCommand(help: 'Initialize a Google Drive home directory')
  init({ @Option(help: 'The root directory for Google Drive. Defaults to your current directory') String driveHome }) async {
    String p = driveHome == null || driveHome.isEmpty ? path.current : driveHome; //path ? path : path.current;
    bool firstTime = ! await context.credentialsExist(p);
    context.askForAuthorization(p);
  }
}


// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../dart/resolution/driver_resolution.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(RecursiveCompileTimeConstantTest);
  });
}

@reflectiveTest
class RecursiveCompileTimeConstantTest extends DriverResolutionTest {
  test_private() async {
    await assertErrorsInCode('''
f({var _p}) {}
''', [
      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 3, 6),
    ]);
  }

  test_fieldFormal() async {
    await assertErrorsInCode(r'''
class A {
  var _p;
  A({this._p: 0});
}
''', [
      error(HintCode.UNUSED_FIELD, 16, 2),
      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 25, 7),
    ]);
  }

  test_withDefaultValue() async {
    await assertErrorsInCode('''
f({_p : 0}) {}
''', [
      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 3, 2),
    ]);
  }
}

Rename an incorrectly named test class

// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../dart/resolution/driver_resolution.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(PrivateOptionalParameterTest);
  });
}

@reflectiveTest
class PrivateOptionalParameterTest extends DriverResolutionTest {
  test_private() async {
    await assertErrorsInCode('''
f({var _p}) {}
''', [
      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 3, 6),
    ]);
  }

  test_fieldFormal() async {
    await assertErrorsInCode(r'''
class A {
  var _p;
  A({this._p: 0});
}
''', [
      error(HintCode.UNUSED_FIELD, 16, 2),
      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 25, 7),
    ]);
  }

  test_withDefaultValue() async {
    await assertErrorsInCode('''
f({_p : 0}) {}
''', [
      error(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, 3, 2),
    ]);
  }
}


import 'dart:io';
import 'dart:convert';

/// This script reads the JSON object from the file at args[0] and
/// adds data to it from the environment.  Args[1] should be the timestamp
/// (as epoch seconds) of the current Git commit being tested.
void main(List<String> args) {
  Map<String, dynamic> map = jsonDecode(File(args[0]).readAsStringSync());
  final env = Platform.environment;
  map['commit_hash'] = env['BUILDBOT_REVISION'];
  map['commit_time'] = args[1];
  map['builder_name'] = env['SWARMING_BOT_ID'];
  map['bot_name'] = env['BUILDBOT_BUILDERNAME'];
  File(args[0]).writeAsStringSync(jsonEncode(map));
}

Add commit hash to results upload on builders

import 'dart:io';
import 'dart:convert';

/// This script reads the JSON object from the file at args[0] and
/// adds data to it from the environment.  Args[1] should be the timestamp
/// (as epoch seconds) of the current Git commit being tested.
/// Args[2] should be the hash of the current Git commit under test.
void main(List<String> args) {
  Map<String, dynamic> map = jsonDecode(File(args[0]).readAsStringSync());
  final env = Platform.environment;
  map['commit_time'] = args[1];
  map['commit_hash'] = args[2];
  map['builder_name'] = env['SWARMING_BOT_ID'];
  map['bot_name'] = env['BUILDBOT_BUILDERNAME'];
  File(args[0]).writeAsStringSync(jsonEncode(map));
}


// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * This contains a reader that accesses data from local files, so it can't
 * be run in the browser.
 */

library file_data_reader;

import 'dart:io';
import 'intl_helpers.dart';

class FileDataReader implements LocaleDataReader {

  /// The base path from which we will read data.
  String path;

  FileDataReader(this.path);

  /// Read the locale data found for [locale] on our [path].
  Future read(String locale) {
    var file = new File('$path$locale.json');
    return file.readAsText();
  }
}

Rename File.readAsText to File.readAsString. There is no Text type in Dart and the methods return Strings.

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/**
 * This contains a reader that accesses data from local files, so it can't
 * be run in the browser.
 */

library file_data_reader;

import 'dart:io';
import 'intl_helpers.dart';

class FileDataReader implements LocaleDataReader {

  /// The base path from which we will read data.
  String path;

  FileDataReader(this.path);

  /// Read the locale data found for [locale] on our [path].
  Future read(String locale) {
    var file = new File('$path$locale.json');
    return file.readAsString();
  }
}


import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../../features/settings/presentation/bloc/settings_bloc.dart';
import 'settings_not_loaded.dart';

class PageBody extends StatelessWidget {
  final Widget child;

  const PageBody({
    Key? key,
    required this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: BlocBuilder<SettingsBloc, SettingsState>(
        builder: (context, state) {
          if (state is SettingsSuccess) return child;

          return const SettingsNotLoaded();
        },
      ),
    );
  }
}

Add optional loading indicator to PageBody.

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../../features/settings/presentation/bloc/settings_bloc.dart';
import 'settings_not_loaded.dart';

class PageBody extends StatelessWidget {
  final Widget child;
  final bool loading;

  const PageBody({
    Key? key,
    required this.child,
    this.loading = false,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: BlocBuilder<SettingsBloc, SettingsState>(
        builder: (context, state) {
          if (state is SettingsSuccess) {
            return Stack(
              children: [
                if (loading) const LinearProgressIndicator(),
                child,
              ],
            );
          }

          return const SettingsNotLoaded();
        },
      ),
    );
  }
}


library test.event_emitter;

import 'src/event_emitter_test.dart' as event_emitter_test;
import 'package:test/test.dart';

void main () {
    group('[Event emitter]', event_emitter_test.main);
}

Add event objects' tests to travis builds

library test.event_emitter;

import 'src/event_emitter_test.dart' as event_emitter_test;
import 'src/event_emitter_with_event_objects_test.dart' as event_objects_test;
import 'package:test/test.dart';

void main () {
    group('[Event emitter]', event_emitter_test.main);
    group('[Event emitter with objects]', event_objects_test.main);
}