-
<%= _('All Templates') %>
- <%= paginable_renderise(
- partial: 'paginable/templates/all',
- controller: 'paginable/templates',
- action: 'all',
- scope: all_templates,
- query_params: { sort_field: 'templates.title', sort_direction: :asc },
- locals: {current_org: current_org.id, published: published, scopes: scopes[:all], hide_actions: true}) %>
+
+
+
+
<%= title %>
+
+ <% filter_path = "/paginable/templates/#{action}/#{1}" %>
+ <% qry = query_params.collect{ |k,v| "#{k}=#{v}" }.join('&') %>
+
+ <% if isActivePage(customisable_org_admin_templates_path) %>
+ <%= link_to _('All (%{count})') % { count: all_count}, "#{filter_path}?#{qry}", 'data-remote': "true" %>
+ <%= link_to _('Published (%{count})') % { count: published_count}, "#{filter_path}?f=published{qry}", 'data-remote': "true" %>
+ <%= link_to _('Unpublished (%{count})') % { count: unpublished_count}, "#{filter_path}?f=unpublished{qry}", 'data-remote': "true" %>
+ <%= link_to _('Not customised (%{count})') % { count: not_customized_count}, "#{filter_path}?f=not-customised{qry}", 'data-remote': "true" %>
+ <% else %>
+ <%= link_to _('All (%{count})') % { count: all_count}, "#{filter_path}?#{qry}", 'data-remote': "true" %>
+ <%= link_to _('Published (%{count})') % { count: published_count}, "#{filter_path}?f=published{qry}", 'data-remote': "true" %>
+ <%= link_to _('Unpublished (%{count})') % { count: unpublished_count}, "#{filter_path}?f=unpublished{qry}", 'data-remote': "true" %>
+ <% end %>
+
+
+ <%= paginable_renderise(
+ partial: "paginable/templates/#{action}",
+ controller: 'paginable/templates',
+ action: action,
+ scope: templates,
+ query_params: { sort_field: 'templates.title', sort_direction: :asc },
+ locals: local_assigns) %>
+
- <% end %>
-
-
<%= current_user.can_super_admin? ? _('%{org_name} Templates') % { org_name: current_user.org.name } : _('Own Templates') %>
- <%= paginable_renderise(
- partial: 'paginable/templates/orgs',
- controller: 'paginable/templates',
- action: 'orgs',
- scope: own_templates,
- query_params: { sort_field: 'templates.title', sort_direction: :asc },
- locals: {current_org: current_org.id, published: published, scopes: scopes[:orgs], hide_actions: false}) %>
-
- <% if !current_org.funder_only? %>
-
-
<%= _('Customizable Templates') %>
- <%= paginable_renderise(
- partial: 'paginable/templates/funders',
- controller: 'paginable/templates',
- action: 'funders',
- scope: customizable_templates,
- query_params: { sort_field: 'templates.title', sort_direction: :asc },
- locals: {current_org: current_org.id, customizations: customized_templates, published: published, scopes: scopes[:funders]}) %>
-
- <% end %>
diff --git a/app/views/org_admin/templates/new.html.erb b/app/views/org_admin/templates/new.html.erb
deleted file mode 100644
index facbe19..0000000
--- a/app/views/org_admin/templates/new.html.erb
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
- <%= _('New template') %>
-
-
- <%= link_to _('View all templates'), "#{org_admin_templates_path}#organisation-templates", class: "btn btn-primary" %>
-
-
-
-
-
- <%= raw _('
To create a new template, first enter a title and description. Once you have saved this you will be presented with options to add one or more phases.
')%>
- <%= form_for :template, url: {action: "create"} do |f| %>
-
- <%= f.label(:title, _('Title') ,class: 'control-label') %>
- <%= f.text_field :title, as: :string,
- class: "form-control", "data-toggle": "tooltip", title: _('Please enter a title for your template.') %>
-
-
-
- <% end %>
-
-
\ No newline at end of file
diff --git a/app/views/paginable/notifications/_index.html.erb b/app/views/paginable/notifications/_index.html.erb
new file mode 100644
index 0000000..324e720
--- /dev/null
+++ b/app/views/paginable/notifications/_index.html.erb
@@ -0,0 +1,20 @@
+
+
+
+ <%= _('Title') %> <%= paginable_sort_link('title') %>
+ <%= _('Level') %> <%= paginable_sort_link('level') %>
+ <%= _('Start') %> <%= paginable_sort_link('starts_at') %>
+ <%= _('Expiration') %> <%= paginable_sort_link('expires_at') %>
+
+
+
+ <% scope.each do |notification| %>
+
+ <%= link_to notification.title, edit_super_admin_notification_path(notification) %>
+ <%= notification.level %>
+ <%= notification.starts_at %>
+ <%= notification.expires_at %>
+
+ <% end %>
+
+
diff --git a/app/views/paginable/orgs/_index.html.erb b/app/views/paginable/orgs/_index.html.erb
index 7dd18b6..21a92f8 100644
--- a/app/views/paginable/orgs/_index.html.erb
+++ b/app/views/paginable/orgs/_index.html.erb
@@ -15,7 +15,7 @@
<%= org.name %>
<%= org.contact_email %>
<%= org.org_type_to_s %>
-
<%= org.templates.collect(&:dmptemplate_id).uniq.length %>
+
<%= org.templates.collect(&:family_id).uniq.length %>
-
-
-
-
- <% if scopes.present? %>
-
- <% scopes.keys.each do |k| %>
- <% unless k == :dmptemplate_ids %>
- <%= link_to "#{k.capitalize} (#{scopes[k]})",
- "#{all_paginable_templates_path(1)}?scope=#{k}",
- class: 'template-scope', 'data-remote': true %>
- <% end %>
- <% end %>
-
- <% end %>
-
- <%= _('Template Name') %> <%= paginable_sort_link('templates.title') %>
- <%= _('Organisation') %> <%= paginable_sort_link('orgs.name') %>
- <%= _('Status') %> <%= paginable_sort_link('templates.published') %>
- <%= _('Edited Date') %> <%= paginable_sort_link('templates.updated_at') %>
-
-
-
- <% scope.each do |template| %>
-
-
- <%= template.title %>
-
-
- <%= template.org.name %>
-
-
- <% if template.dirty? %>
- <%= _('Unpublished changes') %>
- <% elsif template.published? %>
- <%= _('Published') %>
- <% else %>
- <%= _('Unpublished') %>
- <% end %>
-
-
- <% last_temp_updated = template.updated_at %>
- <%= l last_temp_updated.to_date, formats: :short %>
-
-
- <% end %>
-
-
-
\ No newline at end of file
diff --git a/app/views/paginable/templates/_customisable.html.erb b/app/views/paginable/templates/_customisable.html.erb
new file mode 100644
index 0000000..20cb3b1
--- /dev/null
+++ b/app/views/paginable/templates/_customisable.html.erb
@@ -0,0 +1,86 @@
+<% # locals: templates %>
+
+
+
+
+ <%= _('Template Name') %> <%= paginable_sort_link('templates.title') %>
+ <%= _('Funder') %> <%= paginable_sort_link('orgs.name') %>
+ <%= _('Status') %>
+ <%= _('Edited Date') %> <%= paginable_sort_link('templates.updated_at') %>
+
+
+
+
+ <% scope.each do |template| %>
+ <% customization = customizations.find{ |customization| customization.customization_of == template.family_id } %>
+
+
+ <%= "#{template.is_default ? '* ' : ''}#{template.title}" %>
+
+
+ <%= template.org.name %>
+
+
+ <% if customization.present? %>
+ <% if customization.upgrade_customization? %>
+ <% tooltip = _("Select 'Transfer customisation' in the Actions menu to review your customisation(s) and make any necessary changes. When you are done, you must return to the Actions menu and publish your customisation(s).") %>
+ <%= _('Original funder template has changed!') %><%= tooltip %>
+
+ <% else %>
+ <% if customization.published? %>
+ <%= _('Published') %>
+ <% elsif customization.draft? %>
+ <% tooltip = _('You have unpublished changes! Select "Publish changes" in the Actions menu when you are ready to make them available to users.') %>
+ <%= _('Published') %> <%= tooltip %>
+
+ <% else %>
+ <%= _('Unpublished') %>
+ <% end %>
+ <% end %>
+ <% else %>
+ <%= _('Not customized') %>
+ <% end %>
+
+
+ <% last_temp_updated = template.updated_at %>
+ <%= l last_temp_updated.to_date, formats: :short %>
+
+
+
+
+ <%= _('Actions') %>
+
+
+
+
+
+ <% end %>
+
+
+
\ No newline at end of file
diff --git a/app/views/paginable/templates/_funders.html.erb b/app/views/paginable/templates/_funders.html.erb
deleted file mode 100644
index d0beef2..0000000
--- a/app/views/paginable/templates/_funders.html.erb
+++ /dev/null
@@ -1,93 +0,0 @@
-<% # locals: templates, current_org %>
-
-
-
-
- <% if scopes.present? %>
-
- <% scopes.keys.each do |k| %>
- <% unless k == :dmptemplate_ids %>
- <% label = (['published', 'unpublished'].include?(k.to_s) ? _('Customization %{publication_status}') % { publication_status: k } : k.capitalize) %>
- <%= link_to "#{label} (#{scopes[k]})", "#{funders_paginable_templates_path(1)}?scope=#{k}", class: 'template-scope', 'data-remote': true %>
- <% end %>
- <% end %>
-
- <% end %>
-
- <%= _('Template Name') %> <%= paginable_sort_link('templates.title') %>
- <%= _('Funder') %> <%= paginable_sort_link('orgs.name') %>
- <%= _('Status') %>
- <%= _('Edited Date') %> <%= paginable_sort_link('templates.updated_at') %>
-
-
-
-
- <% scope.each do |template| %>
- <% customization = customizations[template.dmptemplate_id] %>
-
-
- <%= "#{template.is_default? ? '* ' : ''}#{template.title}" %>
-
-
- <%= raw template.org.name %>
-
-
- <% if customization.present? %>
-
- <% if customization.updated_at < template.updated_at %>
- <%= _('Original funder template has changed!')%>
- <% elsif !template.published? %>
-
- <%= b_label = _('Funder version is unpublished') %>
- <% elsif customization.dirty? %>
- <%= _('You have unpublished changes') %>
- <% elsif customization.published? %>
- <%= _('Published') %>
- <% else %>
- <%= _('Unpublished') %>
- <% end %>
- <% else %>
- <%= _('Not Customised') %>
- <% end %>
-
-
- <% last_temp_updated = template.updated_at %>
- <%= l last_temp_updated.to_date, formats: :short %>
-
-
-
-
- <%= _('Actions') %>
-
-
-
-
-
- <% end %>
-
-
-
\ No newline at end of file
diff --git a/app/views/paginable/templates/_history.html.erb b/app/views/paginable/templates/_history.html.erb
index bf54288..3a081ce 100644
--- a/app/views/paginable/templates/_history.html.erb
+++ b/app/views/paginable/templates/_history.html.erb
@@ -1,35 +1,46 @@
-<%# locals: { controller, action, paginable, scope, current } %>
- <%= _('Title') %> <%= paginable_sort_link('title') %>
- <%= _('Version') %> <%= paginable_sort_link('version') %>
- <%= _('Published') %> <%= paginable_sort_link('published') %>
- <%= _('Last updated') %> <%= paginable_sort_link('updated_at') %>
+ <%= _('Title') %> <%= paginable_sort_link('templates.title') %>
+ <%= _('Version') %> <%= paginable_sort_link('templates.version') %>
+ <%= _('Published') %> <%= paginable_sort_link('templates.published') %>
+ <%= _('Last updated') %> <%= paginable_sort_link('templates.updated_at') %>
<%= _('Actions') %>
- <% scope.each do |org_template| %>
+ <% scope.each do |template| %>
- <%= org_template.title%>
- <% if org_template == current && !org_template.published%>
+ <%= template.title%>
+ <% if template.draft? && template.latest? %>
<%=_('Draft')%>
<% end %>
- <%= org_template.version %>
+ <%= template.version %>
- <%= (org_template.published? ? _('Yes') : _('No')) %>
+ <%= (template.published? ? _('Yes') : _('No')) %>
- <%= l org_template.updated_at.to_date, formats: :short %>
+ <%= l template.updated_at.to_date, formats: :short %>
- <%= link_to (org_template == current ? _('Edit') : _('View')), edit_org_admin_template_path(id: org_template), class: "dmp_table_link"%>
+ <% if template.customization_of.present? %>
+ <% if template.latest? %>
+ <%= link_to _('Edit customizations'), org_admin_template_path(id: template.id), class: "dmp_table_link" %>
+ <% else %>
+ <%= link_to _('View customizations'), org_admin_template_path(id: template.id), class: "dmp_table_link" %>
+ <% end %>
+ <% else %>
+ <% if template.latest? %>
+ <%= link_to _('Edit'), edit_org_admin_template_path(id: template.id), class: "dmp_table_link" %>
+ <% else %>
+ <%= link_to _('View'), org_admin_template_path(id: template.id), class: "dmp_table_link" %>
+ <% end %>
+ <% end %>
<% end %>
diff --git a/app/views/paginable/templates/_index.html.erb b/app/views/paginable/templates/_index.html.erb
new file mode 100644
index 0000000..12a98f2
--- /dev/null
+++ b/app/views/paginable/templates/_index.html.erb
@@ -0,0 +1,40 @@
+<% # locals: templates %>
+
+
+
+
+ <%= _('Template Name') %> <%= paginable_sort_link('templates.title') %>
+ <%= _('Organisation') %> <%= paginable_sort_link('orgs.name') %>
+ <%= _('Status') %>
+ <%= _('Edited Date') %> <%= paginable_sort_link('templates.updated_at') %>
+
+
+
+ <% scope.each do |template| %>
+
+
+ <%= "#{template.is_default? ? '* ' : ''}#{template.title}" %>
+
+
+ <%= template.org.name %>
+
+
+ <% if template.published? %>
+ <%= _('Published') %>
+ <% elsif template.draft? %>
+ <% tooltip = _('This template is published changes but has unpublished changes!') %>
+ <%= _('Published') %> <%= tooltip %>
+
+ <% else %>
+ <%= _('Unpublished') %>
+ <% end %>
+
+
+ <% last_temp_updated = template.updated_at %>
+ <%= l last_temp_updated.to_date, formats: :short %>
+
+
+ <% end %>
+
+
+
\ No newline at end of file
diff --git a/app/views/paginable/templates/_organisational.html.erb b/app/views/paginable/templates/_organisational.html.erb
new file mode 100644
index 0000000..98c7904
--- /dev/null
+++ b/app/views/paginable/templates/_organisational.html.erb
@@ -0,0 +1,80 @@
+<% # locals: templates %>
+
+
+
+
+ <%= _('Template Name') %> <%= paginable_sort_link('templates.title') %>
+ <% if action == 'organisational' %>
+ <%= _('Description') %> <%= paginable_sort_link('templates.description') %>
+ <% else %>
+ <%= (action == 'customizable' ? _('Funder') : _('Organisation')) %> <%= paginable_sort_link('orgs.name') %>
+ <% end %>
+ <%= _('Status') %>
+ <%= _('Edited Date') %> <%= paginable_sort_link('templates.updated_at') %>
+ <% if action != 'index' %>
+
+ <% end %>
+
+
+
+ <% scope.each do |template| %>
+
+
+ <%= template.title %>
+
+
+ <%= action == 'organisational' ? raw(template.description) : template.org.name %>
+
+
+ <%# Leaving this line here as a placeholder for determining how to notify user of changes now that dirty flag is removed %>
+ <%# if template.dirty? %>
+ <%# _('Unpublished changes') %>
+
+ <% if template.published? %>
+ <%= _('Published') %>
+ <% elsif template.draft? %>
+ <% tooltip = _('You have unpublished changes! Select "Publish changes" in the Actions menu when you are ready to make them available to users.') %>
+ <%= _('Published') %> <%= tooltip %>
+
+ <% else %>
+ <%= _('Unpublished') %>
+ <% end %>
+
+
+ <% last_temp_updated = template.updated_at %>
+ <%= l last_temp_updated.to_date, formats: :short %>
+
+ <% if action != 'index' %>
+
+
+
+ <%= _('Actions') %>
+
+
+
+
+ <% end %>
+
+ <% end %>
+
+
+
\ No newline at end of file
diff --git a/app/views/paginable/templates/_orgs.html.erb b/app/views/paginable/templates/_orgs.html.erb
deleted file mode 100644
index 7361570..0000000
--- a/app/views/paginable/templates/_orgs.html.erb
+++ /dev/null
@@ -1,80 +0,0 @@
-<% # locals: templates, current_org %>
-
-
-
-
- <% if scopes.present? %>
-
- <% scopes.keys.each do |k| %>
- <% unless k == :dmptemplate_ids %>
- <%= link_to "#{k.capitalize} (#{scopes[k]})", "#{orgs_paginable_templates_path(1)}?scope=#{k}", class: 'template-scope', 'data-remote': true %>
- <% end %>
- <% end %>
-
- <% end %>
-
- <%= _('Template Name') %> <%= paginable_sort_link('templates.title') %>
- <%= _('Description') %> <%= paginable_sort_link('templates.description') %>
- <%= _('Status') %>
- <%= _('Edited Date') %> <%= paginable_sort_link('templates.updated_at') %>
-
-
-
-
- <% scope.each do |template| %>
-
-
- <%= template.title %>
-
-
- <%= raw(template.description) %>
-
-
- <% if published[template.dmptemplate_id].present? && !template.published? %>
- <%= _('Unpublished changes') %>
- <% elsif template.published? %>
- <%= _('Published') %>
- <% else %>
- <%= _('Unpublished') %>
- <% end %>
-
-
- <% last_temp_updated = template.updated_at %>
- <%= l last_temp_updated.to_date, formats: :short %>
-
-
-
- <% # Span used to trigger the display of the action dropdowns via JS %>
- <%= template.org.id %>
-
-
- <%= _('Actions') %>
-
-
-
-
-
- <% end %>
-
-
-
\ No newline at end of file
diff --git a/app/views/paginable/templates/_publicly_visible.html.erb b/app/views/paginable/templates/_publicly_visible.html.erb
index 58c030f..6c43a0b 100644
--- a/app/views/paginable/templates/_publicly_visible.html.erb
+++ b/app/views/paginable/templates/_publicly_visible.html.erb
@@ -15,8 +15,8 @@
<%= template.title %>
- <%= link_to _('DOCX'), template_export_path(template.dmptemplate_id, format: :docx), target: '_blank' %>
- <%= link_to _('PDF'), template_export_path(template.dmptemplate_id, format: :pdf), target: '_blank' %>
+ <%= link_to _('DOCX'), template_export_path(template.family_id, format: :docx), target: '_blank' %>
+ <%= link_to _('PDF'), template_export_path(template.family_id, format: :pdf), target: '_blank' %>
<%= template.org.name %>
<%= l(template.updated_at.to_date, formats: :short) %>
diff --git a/app/views/phases/_admin_add.html.erb b/app/views/phases/_admin_add.html.erb
deleted file mode 100644
index 2ab4baf..0000000
--- a/app/views/phases/_admin_add.html.erb
+++ /dev/null
@@ -1,30 +0,0 @@
-<%= _('Phase details') %>
-<%= _('When you create a new phase for your template, a version will automatically be created. Once you complete the form below you will be provided with options to create sections and questions.') %>
-<%= form_for :phase, { url: admin_create_phase_path(r: current_tab) } do |f| %>
- <%= f.hidden_field :template_id, value: @template.id%>
-
- <%= f.label(:title, _('Title') ,class: "control-label") %>
- <%= f.text_field(:title, class: "form-control", 'aria-required': false, 'data-toggle': 'tooltip', title: _('Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP')) %>
-
-
-
-
-
-
-
- <%= f.button(_('Save'), class: 'btn btn-default', type: "submit") %>
- <%= link_to(_('Cancel'), edit_org_admin_template_path(@template), { class: 'btn btn-default', role: "button" }) %>
-
-<% end %>
\ No newline at end of file
diff --git a/app/views/phases/_admin_show.html.erb b/app/views/phases/_admin_show.html.erb
deleted file mode 100644
index d29df78..0000000
--- a/app/views/phases/_admin_show.html.erb
+++ /dev/null
@@ -1,85 +0,0 @@
-<% # locals: { phase, template, edit, current_section } %>
-<%= _('Phase details')%>
-
-
- <% if phase.modifiable && edit %>
-
- <%= render partial: "phases/edit_phase", locals: { phase: phase, current_tab: current_tab }%>
-
- <% end %>
-
-
-
-
-
- <%= render partial: "phases/show_phase", locals: { phase: phase, edit: edit, current_tab: current_tab } %>
-
-
-
-
-
- <% if phase.sections.length > 1 %>
-
- <% end %>
-
-
-
-
-
-
- <% phase.sections.each do |section| %>
-
-
-
"
- class="panel-collapse collapse<%= " in" if section.id == current_section %>"
- role="tabpanel"
- aria-labelledby="<%= "headingSection#{section.id}" %>">
-
- <% if edit && section.modifiable %>
- <%= render partial: 'sections/edit_section', locals: { template: template, section: section, edit: edit, phase: phase, current_tab: current_tab } %>
- <% else %>
- <%= render partial: 'sections/show_section', locals: { template: template, section: section, current_tab: current_tab, edit: edit } %>
- <% end %>
-
-
-
- <% end %>
-
- <% if edit || template.customization_of.present? %>
-
-
-
- <%= link_to(_('Add Section'), "#section_new#{phase.id}", { class: "btn btn-default section_new_link", role: "button" }) %>
-
-
-
-
- <%= render partial: 'sections/add_section', locals: { phase: phase, current_tab: current_tab } %>
-
-
-
- <% end %>
-
-
diff --git a/app/views/phases/_edit_phase.html.erb b/app/views/phases/_edit_phase.html.erb
deleted file mode 100644
index ec55c1f..0000000
--- a/app/views/phases/_edit_phase.html.erb
+++ /dev/null
@@ -1,29 +0,0 @@
-<%= form_for :phase, { url: admin_update_phase_path(phase.id, r: current_tab), html: { method: :put }} do |f| %>
-
- <%= f.label(:title, _('Title') ,class: "control-label") %>
- <%= f.text_field(:title, class: "form-control", 'aria-required': false, 'data-toggle': 'tooltip', title: _('Enter a title for the phase e.g. intial DMP, full DMP... This is what users will see in the tabs when completing a plan. If you only have one phase, call it something generic e.g. Glasgow DMP')) %>
-
-
-
-
-
-
-
-<% end %>
\ No newline at end of file
diff --git a/app/views/phases/_edit_plan_answers.html.erb b/app/views/phases/_edit_plan_answers.html.erb
index bad5182..41cc613 100644
--- a/app/views/phases/_edit_plan_answers.html.erb
+++ b/app/views/phases/_edit_plan_answers.html.erb
@@ -38,7 +38,7 @@
<%= section.title %>
<% if plan.present? %>
- <%= render :partial => "/sections/progress", locals: { section: section, plan: plan } %>
+ <%= render :partial => "/org_admin/sections/progress", locals: { section: section, plan: plan } %>
<% end %>
diff --git a/app/views/phases/_guidances_notes.html.erb b/app/views/phases/_guidances_notes.html.erb
index 7c89413..9ad6e2a 100644
--- a/app/views/phases/_guidances_notes.html.erb
+++ b/app/views/phases/_guidances_notes.html.erb
@@ -54,7 +54,7 @@
<% num_annotations = 0 %>
<% i = 0 %>
<% annotations.each do |annotation| %>
- <%= render partial: 'annotations/show',
+ <%= render partial: 'org_admin/annotations/show',
locals: {
template: template,
example_answer: (annotation.example_answer? ? annotation : nil),
diff --git a/app/views/phases/_overview.html.erb b/app/views/phases/_overview.html.erb
index 829b724..f216c85 100644
--- a/app/views/phases/_overview.html.erb
+++ b/app/views/phases/_overview.html.erb
@@ -3,7 +3,7 @@
<%= raw(phase.description) %>
diff --git a/app/views/phases/_show_phase.html.erb b/app/views/phases/_show_phase.html.erb
deleted file mode 100644
index 325a3b5..0000000
--- a/app/views/phases/_show_phase.html.erb
+++ /dev/null
@@ -1,18 +0,0 @@
-
- <%= _('Title') %>
- <%= phase.title %>
- <%= _('Order of display') %>
- <%= phase.number %>
- <%= _('Description') %>
- <%= raw phase.description %>
-
-<% if phase.modifiable && edit %>
-
-
- <%= link_to(_('Edit phase details'), '#', { class: "btn btn-default phase_edit_link", role: "button" }) %>
- <%= link_to(_('Preview'), admin_preview_phase_path(phase, r: current_tab), { class: 'btn btn-default phase_preview_link', role: 'button' }) %>
-
-
-<% end %>
-
-
diff --git a/app/views/phases/admin_preview.html.erb b/app/views/phases/admin_preview.html.erb
deleted file mode 100644
index 338caeb..0000000
--- a/app/views/phases/admin_preview.html.erb
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
<%= @template.title %>
-
-
- <%= link_to _('Back to edit phase'), admin_show_phase_path(id: @phase.id, r: @current_tab), class: 'btn btn-primary' %>
- <%= link_to _('View all templates'), org_admin_templates_path(r: @current_tab), class: 'btn btn-primary' %>
-
-
-
-
-
-
-
- <%= render partial: "/org_admin/templates/admin_nav_tabs", locals: { template: @template, active: @phase.id, edit: false, current_tab: @current_tab } %>
-
-
-
-
-
- <%= render partial: '/phases/edit_plan_answers', locals: { plan: nil, phase: @phase, readonly: true, question_guidance: {}, edit: false, guidance_groups: [], base_template_org: @base_template_org } %>
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/views/phases/edit.html.erb b/app/views/phases/edit.html.erb
index c135c06..f54c5f3 100644
--- a/app/views/phases/edit.html.erb
+++ b/app/views/phases/edit.html.erb
@@ -7,6 +7,6 @@
- <%= render partial: 'edit_plan_answers', layout: 'plans/navigation', locals: local_assigns %>
+ <%= render partial: 'phases/edit_plan_answers', layout: 'plans/navigation', locals: local_assigns %>
\ No newline at end of file
diff --git a/app/views/plans/_navigation.html.erb b/app/views/plans/_navigation.html.erb
index 20cb5d0..1201abf 100644
--- a/app/views/plans/_navigation.html.erb
+++ b/app/views/plans/_navigation.html.erb
@@ -7,8 +7,8 @@
<%= link_to(_('Plan overview'), overview_plan_path(plan), role: 'tab', 'aria-controls': 'content') %>
<% phases.each do |phase| %>
-
-
+
+
<%= (phases.size > 1 ? phase.title : _('Write Plan')) %>
@@ -18,7 +18,7 @@
<%= _('Share') %>
<% end %>
- <% if !plan.reviewable_by?(current_user.id) %>
+ <% if plan.readable_by?(current_user.id) %>
<%= _('Download') %>
diff --git a/app/views/question_options/_option_fields.html.erb b/app/views/question_options/_option_fields.html.erb
deleted file mode 100644
index 0282d82..0000000
--- a/app/views/question_options/_option_fields.html.erb
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
- <%= _('Order')%>
-
-
- <%= _('Text')%>
-
-
- <%= _('Default')%>
-
-
-
-
-<% if q.question_options.count == 0 %>
- <% 2.times {q.question_options.build } %>
-<% end %>
-<% i = 0 %>
- <% q.question_options.to_a.sort_by{|op| op['number']}.each do |options_q| %>
- <%= f.fields_for :question_options, options_q do |op|%>
- <% i = i + 1 %>
- <% options_q.number = i %>
-
-
- <%= op.number_field :number, in: 1..20, class: 'form-control' %>
-
-
- <%= op.text_field :text, as: :string, class: 'form-control' %>
-
-
- <%= op.check_box :is_default %>
-
-
-
- <% end %>
- <% end %>
-
diff --git a/app/views/questions/_add_question.html.erb b/app/views/questions/_add_question.html.erb
deleted file mode 100644
index 5a9c3f1..0000000
--- a/app/views/questions/_add_question.html.erb
+++ /dev/null
@@ -1,92 +0,0 @@
-
-<% @new_question = Question.new %>
-<% @new_question.number = section.questions.count + 1 %>
-<%= form_for @new_question, url: admin_create_question_path(r: current_tab) , html: {id: "new_question_#{section.id}", class: 'question_form'} do |f| %>
- <%= f.hidden_field :section_id, value: section.id %>
- <%= hidden_field_tag :section_id, section.id, class: "section_id_new" %>
-
-
-
- <%= f.label(:number, _('Question Number'), class: "control-label") %>
- <%= f.number_field(:number, in: 1..50, class: "form-control", "aria-required": true, 'aria-required': true) %>
-
-
-
-
- <%= f.label(:text, _('Question text'), class: "control-label") %>
- <%= f.text_area(:text, class: "question") %>
-
-
-
-
-
-
-
-
-
- <%= f.check_box :option_comment_display, as: :check_boxes %><%= _('Display additional comment area.') %>
-
-
-
-
-
-
-
-
-
-
- <%= render partial: 'org_admin/shared/theme_selector',
- locals: { f: f, all_themes: Theme.all.order("title"),
- popover_message: _('Select one or more themes that are relevant to this question. This will allow similarly themed organisation-level guidance to appear alongside your question.') } %>
-
-
-<% end %>
diff --git a/app/views/questions/_edit_question.html.erb b/app/views/questions/_edit_question.html.erb
deleted file mode 100644
index 8d452db..0000000
--- a/app/views/questions/_edit_question.html.erb
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
- <%= form_for(question, url: admin_update_question_path(question, r: current_tab), html: { method: :put, class: 'question_form' }) do |f| %>
- <%= f.hidden_field :id,{ class: "quest_id" } %>
- <%= hidden_field_tag :question_id, question.id, class: "question_id" %>
-
-
- <%= f.label(:number, _('Question Number'), class: "control-label") %>
- <%= f.number_field(:number, in: 1..50, class: "form-control", "aria-required": true, 'aria-required': true) %>
-
-
-
- <%= f.label(:text, _('Question text'), class: "control-label") %>
- <%= f.text_area(:text, class: "question") %>
-
-
-
-
-
- <% comment_disp = question.question_format.option_based? || question.question_format.rda_metadata? %>
-
-
- <%= f.check_box :option_comment_display, as: :check_boxes %><%= _('Display additional comment area.') %>
-
-
-
-
-
-
-
-
-
-
- <%= render partial: 'org_admin/shared/theme_selector',
- locals: { f: f, all_themes: Theme.all.order("title"),
- popover_message: _('Select one or more themes that are relevant to this question. This will allow similarly themed organisation-level guidance to appear alongside your question.') } %>
-
-
- <% end %>
-
-
-
-
-
- <%#= render partial: "guidances/guidance_display", locals: {question: question} %>
-
-
diff --git a/app/views/questions/_new_edit_question_option_based.html.erb b/app/views/questions/_new_edit_question_option_based.html.erb
index 171bf4d..07299d3 100644
--- a/app/views/questions/_new_edit_question_option_based.html.erb
+++ b/app/views/questions/_new_edit_question_option_based.html.erb
@@ -5,7 +5,7 @@
<% options.each do |op| %>
- <%= f.check_box(:question_option_ids, { multiple: true, checked: answer.has_question_option(op.id) }, op.id, nil) %>
+ <%= f.check_box(:question_option_ids, { multiple: true, checked: answer.has_question_option(op.id) || (answer.question_options.empty? && op.is_default?) }, op.id, nil) %>
<%= raw op.text %>
@@ -15,7 +15,7 @@
<% options.each do |op| %>
- <%= f.radio_button :question_option_ids, op.id, { checked: answer.has_question_option(op.id), id: "answer_option_ids_#{op.id}" } %>
+ <%= f.radio_button :question_option_ids, op.id, { checked: answer.has_question_option(op.id) || (answer.question_options.empty? && op.is_default?), id: "answer_option_ids_#{op.id}" } %>
<%= raw op.text %>
@@ -24,7 +24,7 @@
<%
options_html = ""
options.each do |op|
- options_html += answer.has_question_option(op.id) ?
+ options_html += answer.has_question_option(op.id) || (answer.question_options.empty? && op.is_default?) ?
"
#{op.text} " :
"
#{op.text} "
end
diff --git a/app/views/questions/_show_question.html.erb b/app/views/questions/_show_question.html.erb
deleted file mode 100644
index 8a5cc30..0000000
--- a/app/views/questions/_show_question.html.erb
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-
-
-
- <% q_format = question.question_format %>
-
- <%= _('Question number')%>
- <%= question.number %>
- <%= _('Question text')%>
- <%= raw question.text %>
-
-
-
-
- <% if q_format.textfield? || q_format.textarea? %>
- <% if !question.default_value.nil? %>
- <%= _('Default value')%>
- <%= raw question.default_value %>
- <% end %>
- <% end %>
-
- <%= _('Answer format')%>
-
- <%= q_format.title %>
- <% if q_format.option_based? %>
- <%= _('Additional comment area will be displayed.')%>
- <% else %>
- <%= _('No additional comment area will be displayed.')%>
- <% end %>
-
-
- <% if !question.section.phase.template.org.funder? %>
- <% example_answer = question.get_example_answers(@original_org.id).first %>
- <% if example_answer.present? && example_answer.text.present? %>
- <%= _('example answer')%>
- <%= raw example_answer.text %>
- <% end %>
- <% end %>
-
- <% guidance = question.get_guidance_annotation(@original_org.id) %>
- <% if guidance.present? %>
- <%= _('Guidance')%>
- <%= raw guidance.text %>
- <% end %>
-
- <% themes_q = question.themes %>
- <% if !themes_q.nil? %>
- <%= _('Themes')%>
- <%= themes_q.join(', ') %>
- <% end %>
-
-
-
-
-
-
- <% example_answer = question.get_example_answers(current_user.org_id).first %>
- <% guidance = question.get_guidance_annotation(current_user.org_id) %>
- <% editing = (example_answer.present? || guidance.present?) %>
- <% if !question.modifiable %>
-
<%= _('Annotations') %>
-
- <%= render partial: 'annotations/show',
- locals: { example_answer: example_answer,
- guidance: guidance,
- template: template,
- for_plan: false } %>
- <% unless question.modifiable %>
-
- <%= link_to _('%{add_or_edit} Annotations') % { add_or_edit: (editing ? 'Edit' : 'Add') },
- "#annotations_div_#{question.id}", class: "btn btn-default annotations_button", role:"button" %>
-
- <% end %>
-
-
- <%= render partial: 'annotations/new_edit',
- locals: {
- example_answer: example_answer,
- guidance: guidance,
- question: question,
- options: { url: admin_update_annotation_path(r: current_tab), method: 'PUT' }
- } %>
-
- <% end %>
-
- <% if (question.modifiable && edit) %>
- <%= link_to _('Edit question'), "#question_edit#{question.id}", class: "btn btn-default question_edit_link", role: "button" %>
- <%= link_to _('Delete question'), admin_destroy_question_path(question_id: question.id, r: current_tab),
- confirm: _("You are about to delete '%{question_text}'. Are you sure?") % { :question_text => question.text }, method: :delete, class: "btn btn-default", role:"button" %>
- <% end %>
-
-
-
-
-
- <%#= render partial: 'guidances/guidance_display', locals: {question: question} %>
-
-
diff --git a/app/views/sections/_add_section.html.erb b/app/views/sections/_add_section.html.erb
deleted file mode 100644
index d64c5a2..0000000
--- a/app/views/sections/_add_section.html.erb
+++ /dev/null
@@ -1,36 +0,0 @@
-
-<% new_section = Section.new %>
-<% new_section.number = phase.sections.count + 1 %>
-<%= form_for new_section, { url: admin_create_section_path(r: current_tab), html: { class: 'form-horizontal' }} do |f| %>
- <%= f.hidden_field :phase_id, value: phase.id %>
-
-
-
-
- <%= f.text_field(:title, { class: "form-control", 'aria-required': false, placeholder: _('Enter a title for the section') } ) %>
-
-
-
-
-
-
- <%= f.label(:number, _('Order of display'), class: "control-label") %>
-
-
- <%= f.number_field(:number, in: 1..15, class: "form-control", 'aria-required': false, 'data-toggle': 'tooltip', title: _('This allows you to order sections.')) %>
-
-
-
- <%= f.label(:description, _('Description'), class: "control-label") %>
-
">
- <%= text_area_tag('section-desc', '', class: 'tinymce form-control') %>
-
-
-
-
- <%= f.button(_('Save'), class: 'btn btn-default', type: "submit") %>
- <%= link_to(_('Cancel'), '#', { class: 'btn btn-default section_new_cancel', role: "button" }) %>
-
-
-
-<% end %>
\ No newline at end of file
diff --git a/app/views/sections/_edit_section.html.erb b/app/views/sections/_edit_section.html.erb
deleted file mode 100644
index b97d078..0000000
--- a/app/views/sections/_edit_section.html.erb
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
<%= _('Section details') %>
-
-
-
-
- <%= form_for(section, url: admin_update_section_path(section, phase: phase, r: current_tab), html: { method: :put }) do |f| %>
-
- <%= f.label(:title, _('Title') ,class: "control-label") %>
- <%= f.text_field(:title, { class: "form-control", 'aria-required': false, placeholder: _('Enter a title for the section'), 'data-toggle': 'tooltip', title: _('Enter a title for the section')} ) %>
-
-
-
-
-
-
-
- <% end %>
-
-
-
<%= _('Questions') %>
- <% questions = section.questions.order('number') %>
- <% if questions.present? %>
- <% questions.each do |question| %>
-
-
">
- <%= render partial: 'questions/show_question', locals: {template: template, question: question, current_tab: current_tab, edit: edit} %>
-
-
" style="display: none;">
- <%= render partial: 'questions/edit_question', locals: {template: template, question: question, current_tab: current_tab} %>
-
- <%= raw("
") if questions.last.id == question.id %>
- <% end %>
- <% end %>
-
-
-<% if edit %>
-
-
-
- <%= link_to(_('Add Question'), '#', { class: 'btn btn-default question_new_link', role: "button" }) %>
-
-
- <%= render partial: 'questions/add_question', locals: { section: section, current_tab: current_tab } %>
-
-
-
-<% end %>
\ No newline at end of file
diff --git a/app/views/sections/_progress.html.erb b/app/views/sections/_progress.html.erb
deleted file mode 100644
index d02cbac..0000000
--- a/app/views/sections/_progress.html.erb
+++ /dev/null
@@ -1,7 +0,0 @@
-<%# locals: { section, plan } %>
-
-<% num_section_questions = section.questions.size() %>
-<% num_section_answers = section.num_answered_questions(plan) %>
-
- (<%= num_section_answers %> / <%= num_section_questions %>)
-
\ No newline at end of file
diff --git a/app/views/sections/_show_section.html.erb b/app/views/sections/_show_section.html.erb
deleted file mode 100644
index 4848a8c..0000000
--- a/app/views/sections/_show_section.html.erb
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
- <%= raw section.description %>
-
-
-
-
-
-
<%= _('Questions') %>
- <% questions = section.questions.order('number') %>
- <% if questions.present? %>
- <% questions.each do |question| %>
-
-
">
- <%= render partial: 'questions/show_question', locals: {template: template, question: question, current_tab: current_tab, edit: edit} %>
-
- <% if question.modifiable && edit %>
-
" style="display: none;">
- <%= render partial: 'questions/edit_question', locals: {template: template, question: question, current_tab: current_tab} %>
-
- <% end %>
- <% if questions.last.id != question.id %>
-
- <% end %>
- <% end %>
- <% end %>
-
-
\ No newline at end of file
diff --git a/app/views/shared/_my_org.html.erb b/app/views/shared/_my_org.html.erb
index 076501a..66b3415 100644
--- a/app/views/shared/_my_org.html.erb
+++ b/app/views/shared/_my_org.html.erb
@@ -1,7 +1,8 @@
<%= f.label :org_name, _('Organisation'), class: 'control-label' %>
+<% object_name = (f.options[:namespace].present? ? "#{f.options[:namespace]}_#{f.object_name}" : f.object_name) %>
<%= render partial: "shared/accessible_combobox",
- locals: {name: "#{f.object_name}[org_name]",
- id: "#{f.object_name}_org_name",
+ locals: {name: "#{object_name}[org_name]",
+ id: "#{object_name}_org_name",
default_selection: default_org,
models: orgs,
attribute: 'name'} %>
diff --git a/app/views/super_admin/notifications/_form.html.erb b/app/views/super_admin/notifications/_form.html.erb
new file mode 100644
index 0000000..b161b86
--- /dev/null
+++ b/app/views/super_admin/notifications/_form.html.erb
@@ -0,0 +1,66 @@
+<% url = @notification.new_record? ? super_admin_notifications_path : super_admin_notification_path(@notification) %>
+
+<%= form_for @notification, url: url, html: { class: 'notification' } do |f| %>
+
+
+ <%= f.label :title, _('Title'), class: 'control-label' %>
+ <%= f.text_field :title,
+ class: 'form-control',
+ value: @notification.title,
+ "aria-required": true %>
+
+
+
+ <%= f.label :level, _('Level'), class: 'control-label' %>
+ <%= f.select :level,
+ Notification.levels.keys.map { |l| [l.humanize, l] },
+ { value: @notification.level },
+ { class: 'form-control',
+ data: { toggle: 'tooltip', html: true }, title: _('Info: Simple information message, displayed in blue.Warning: warning message, for signaling something unusual, displayed in orange.Danger: error message, for anything critical, displayed in red') } %>
+
+
+
+
+
+ <%= f.check_box :dismissable, style: 'width: auto' %>
+ <%= f.label :dismissable, _('Dismissable'), class: 'control-label' %>
+
+
+
+
+
+ <%= f.label :starts_at, _('Start'), class: 'control-label' %>
+ <%= f.date_field :starts_at,
+ class: 'form-control',
+ value: (@notification.starts_at || Date.today),
+ min: Date.today %>
+
+
+
+ <%= f.label :expires_at, _('Expiration'), class: 'control-label' %>
+ <%= f.date_field :expires_at,
+ class: 'form-control',
+ value: (@notification.expires_at || Date.tomorrow),
+ min: Date.tomorrow %>
+
+
+
+
+ <%= f.label :body, _('Body'), class: 'control-label' %>
+ <%= f.text_area :body,
+ class: 'form-control',
+ value: @notification.body,
+ "aria-required": true %>
+
+
+
+ <%= f.button _('Save'), class: 'btn btn-default', type: 'submit' %>
+ <%= link_to(
+ _('Delete'),
+ super_admin_notification_path(@notification),
+ class: 'btn btn-default',
+ method: :delete,
+ data: { confirm: _('Are you sure you want to delete the notification "%{title}"') % { title: @notification.title }}) unless @notification.new_record? %>
+ <%= link_to _('Cancel'), super_admin_notifications_path, class: 'btn btn-default', role: 'button' %>
+
+<% end %>
diff --git a/app/views/super_admin/notifications/edit.html.erb b/app/views/super_admin/notifications/edit.html.erb
new file mode 100644
index 0000000..558afe0
--- /dev/null
+++ b/app/views/super_admin/notifications/edit.html.erb
@@ -0,0 +1,3 @@
+
<%= _('Editing Notification') %>
+
+<%= render 'form' %>
diff --git a/app/views/super_admin/notifications/index.html.erb b/app/views/super_admin/notifications/index.html.erb
new file mode 100644
index 0000000..381b93e
--- /dev/null
+++ b/app/views/super_admin/notifications/index.html.erb
@@ -0,0 +1,21 @@
+
+
+
<%= _('Notifications') %>
+
+
+
+
+
+ <%= link_to _('+ Add New Notification'), new_super_admin_notification_path, class: 'btn btn-default', role: 'button' %>
+
+
+ <%= paginable_renderise(
+ partial: '/paginable/notifications/index',
+ controller: 'paginable/notifications',
+ action: 'index',
+ scope: notifications,
+ query_params: { sort_field: 'notifications.starts_at', sort_direction: 'desc' })
+ %>
+
+
+
diff --git a/app/views/super_admin/notifications/new.html.erb b/app/views/super_admin/notifications/new.html.erb
new file mode 100644
index 0000000..0e4b494
--- /dev/null
+++ b/app/views/super_admin/notifications/new.html.erb
@@ -0,0 +1,3 @@
+
<%= _('New notification') %>
+
+<%= render 'form' %>
diff --git a/config/application.rb b/config/application.rb
index 4444622..7c2e2f1 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -22,9 +22,6 @@
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
-
- #commented 15.03.2016
- #config.autoload_paths << Rails.root.join('lib')
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
@@ -42,6 +39,8 @@
# Enable escaping HTML in JSON.
config.active_support.escape_html_entities_in_json = true
+
+ config.eager_load_paths << "app/models/scopes"
# Use SQL instead of Active Record's schema dumper when creating the database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
diff --git a/config/initializers/friendly_id.rb b/config/initializers/friendly_id.rb
deleted file mode 100644
index dbbd053..0000000
--- a/config/initializers/friendly_id.rb
+++ /dev/null
@@ -1,88 +0,0 @@
-# FriendlyId Global Configuration
-#
-# Use this to set up shared configuration options for your entire application.
-# Any of the configuration options shown here can also be applied to single
-# models by passing arguments to the `friendly_id` class method or defining
-# methods in your model.
-#
-# To learn more, check out the guide:
-#
-# http://norman.github.io/friendly_id/file.Guide.html
-
-FriendlyId.defaults do |config|
- # ## Reserved Words
- #
- # Some words could conflict with Rails's routes when used as slugs, or are
- # undesirable to allow as slugs. Edit this list as needed for your app.
- config.use :reserved
-
- config.reserved_words = %w(new edit index session login logout users admin
- stylesheets assets javascripts images)
-
- # ## Friendly Finders
- #
- # Uncomment this to use friendly finders in all models. By default, if
- # you wish to find a record by its friendly id, you must do:
- #
- # MyModel.friendly.find('foo')
- #
- # If you uncomment this, you can do:
- #
- # MyModel.find('foo')
- #
- # This is significantly more convenient but may not be appropriate for
- # all applications, so you must explicity opt-in to this behavior. You can
- # always also configure it on a per-model basis if you prefer.
- #
- # Something else to consider is that using the :finders addon boosts
- # performance because it will avoid Rails-internal code that makes runtime
- # calls to `Module.extend`.
- #
- config.use :finders
- #
- # ## Slugs
- #
- # Most applications will use the :slugged module everywhere. If you wish
- # to do so, uncomment the following line.
- #
- # config.use :slugged
- #
- # By default, FriendlyId's :slugged addon expects the slug column to be named
- # 'slug', but you can change it if you wish.
- #
- # config.slug_column = 'slug'
- #
- # When FriendlyId can not generate a unique ID from your base method, it appends
- # a UUID, separated by a single dash. You can configure the character used as the
- # separator. If you're upgrading from FriendlyId 4, you may wish to replace this
- # with two dashes.
- #
- # config.sequence_separator = '-'
- #
- # ## Tips and Tricks
- #
- # ### Controlling when slugs are generated
- #
- # As of FriendlyId 5.0, new slugs are generated only when the slug field is
- # nil, but if you're using a column as your base method can change this
- # behavior by overriding the `should_generate_new_friendly_id` method that
- # FriendlyId adds to your model. The change below makes FriendlyId 5.0 behave
- # more like 4.0.
- #
- # config.use Module.new {
- # def should_generate_new_friendly_id?
- # slug.blank? ||
_changed?
- # end
- # }
- #
- # FriendlyId uses Rails's `parameterize` method to generate slugs, but for
- # languages that don't use the Roman alphabet, that's not usually sufficient.
- # Here we use the Babosa library to transliterate Russian Cyrillic slugs to
- # ASCII. If you use this, don't forget to add "babosa" to your Gemfile.
- #
- # config.use Module.new {
- # def normalize_friendly_id(text)
- # text.to_slug.normalize! :transliterations => [:russian, :latin]
- # end
- # }
-end
diff --git a/config/initializers/rolify.rb b/config/initializers/rolify.rb
deleted file mode 100644
index 45fd03f..0000000
--- a/config/initializers/rolify.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-Rolify.configure do |config|
- # By default ORM adapter is ActiveRecord. uncomment to use mongoid
- # config.use_mongoid
-
- # Dynamic shortcuts for User class (user.is_admin? like methods). Default is: false
- # Enable this feature _after_ running rake db:migrate as it relies on the roles table
- # config.use_dynamic_shortcuts
-end
\ No newline at end of file
diff --git a/config/initializers/swagger.rb b/config/initializers/swagger.rb
deleted file mode 100644
index 7a0eb95..0000000
--- a/config/initializers/swagger.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-class Swagger::Docs::Config
- def self.transform_path(path, api_version)
- # Make a distiction between the APIs and the API documentation paths
- "apidocs/#{path}"
- end
-end
-
-Swagger::Docs::Config.register_apis({
- '0.0' => {
- controller_base_path: '',
- api_file_path: 'public/apidocs',
- base_path: 'http://localhost:3000',
- clean_directory: true,
- api_extention_type: :json
- }
-})
diff --git a/config/locale/en_US/app.po b/config/locale/en_US/app.po
index 8d6f264..a6ba8eb 100644
--- a/config/locale/en_US/app.po
+++ b/config/locale/en_US/app.po
@@ -1137,7 +1137,7 @@
msgstr "Download settings"
msgid "Draft"
-msgstr "Drafgt"
+msgstr "Draft"
msgid "Edit"
msgstr "Edit"
diff --git a/config/routes.rb b/config/routes.rb
index 5e2376b..7f71956 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -61,6 +61,7 @@
put 'update_email_preferences'
put 'org_swap', constraints: {format: [:json]}
end
+ post '/acknowledge_notification', to: 'users#acknowledge_notification'
end
#organisation admin area
@@ -135,40 +136,6 @@
end
end
- resources :phases, path: 'org/admin/templates/phases', only: [] do
- member do
- get 'admin_show'
- get 'admin_preview'
- get 'admin_add'
- put 'admin_update'
- post 'admin_create'
- delete 'admin_destroy'
- end
- end
-
- resources :sections, path: 'org/admin/templates/sections', only: [] do
- member do
- post 'admin_create'
- put 'admin_update'
- delete 'admin_destroy'
- end
- end
-
- resources :questions, path: 'org/admin/templates/questions', only: [] do
- member do
- post 'admin_create'
- put 'admin_update'
- delete 'admin_destroy'
- end
- end
-
- resources :annotations, path: 'org/admin/templates/annotations', only: [] do
- member do
- put 'admin_update'
- delete 'admin_destroy'
- end
- end
-
resources :answers, only: [] do
post 'create_or_update', on: :collection
end
@@ -183,15 +150,6 @@
end
resources :plans do
- resources :phases do
- member do
- get 'edit'
- get 'status'
- post 'update'
- end
- end
-
-
member do
get 'status'
get 'locked'
@@ -212,6 +170,7 @@
post 'set_test', constraints: {format: [:json]}
get 'request_feedback'
get 'overview'
+ get 'phase_status'
end
collection do
@@ -271,11 +230,15 @@
resources :themes, only: [] do
get 'index/:page', action: :index, on: :collection, as: :index
end
+ # Paginable actions for notifications
+ resources :notifications, only: [] do
+ get 'index/:page', action: :index, on: :collection, as: :index
+ end
# Paginable actions for templates
resources :templates, only: [] do
- get 'all/:page', action: :all, on: :collection, as: :all
- get 'funders/:page', action: :funders, on: :collection, as: :funders
- get 'orgs/:page', action: :orgs, on: :collection, as: :orgs
+ get 'index/:page', action: :index, on: :collection, as: :index
+ get 'customisable/:page', action: :customisable, on: :collection, as: :customisable
+ get 'organisational/:page', action: :organisational, on: :collection, as: :organisational
get 'publicly_visible/:page', action: :publicly_visible, on: :collection, as: :publicly_visible
get ':id/history/:page', action: :history, on: :collection, as: :history
end
@@ -296,16 +259,35 @@
get 'feedback_complete'
end
end
- resources :templates, only: [:index, :new, :create, :edit, :update, :destroy] do
+ resources :templates, only: [:index, :show, :new, :edit, :create, :update, :destroy] do
member do
get 'history'
- get 'customize'
- get 'transfer_customization'
- get 'copy', action: :copy, constraints: {format: [:json]}
- get 'publish', action: :publish, constraints: {format: [:json]}
- get 'unpublish', action: :unpublish, constraints: {format: [:json]}
+ post 'customize'
+ post 'transfer_customization'
+ post 'copy', action: :copy, constraints: {format: [:json]}
+ patch 'publish', action: :publish, constraints: {format: [:json]}
+ patch 'unpublish', action: :unpublish, constraints: {format: [:json]}
+ end
+
+ # Used for the organisational and customizable views of index
+ collection do
+ get 'organisational'
+ get 'customisable'
+ end
+
+ resources :phases, only: [:show, :edit, :new, :create, :edit, :update, :destroy] do
+ member do
+ get 'preview'
+ end
+
+ resources :sections, only: [:index, :show, :edit, :update, :create, :destroy] do
+ resources :questions, only: [:show, :edit, :new, :update, :create, :destroy] do
+ end
+ end
end
end
+
+ resources :annotations, only: [:create, :destroy, :update] do ; end
get 'template_options' => 'templates#template_options', constraints: {format: [:json]}
get 'download_plans' => 'plans#download_plans'
@@ -315,5 +297,6 @@
resources :orgs, only: [:index, :new, :create, :edit, :update, :destroy]
resources :themes, only: [:index, :new, :create, :edit, :update, :destroy]
resources :users, only: [:edit, :update]
+ resources :notifications
end
end
diff --git a/db/migrate/20180123161959_change_long_strings_to_text.rb b/db/migrate/20180123161959_change_long_strings_to_text.rb
index 47cef6d..c2ef100 100644
--- a/db/migrate/20180123161959_change_long_strings_to_text.rb
+++ b/db/migrate/20180123161959_change_long_strings_to_text.rb
@@ -1,9 +1,8 @@
class ChangeLongStringsToText < ActiveRecord::Migration
def change
- change_column :orgs, :links, :text
- change_column :templates, :links, :text
- change_column :identifier_schemes, :logo_url, :text
- change_column :identifier_schemes, :user_landing_url, :text
+ # change_column :orgs, :links, :text
+ # change_column :templates, :links, :text
+ # change_column :identifier_schemes, :logo_url, :text
+ # change_column :identifier_schemes, :user_landing_url, :text
end
end
-
diff --git a/db/migrate/20180328115455_create_notifications.rb b/db/migrate/20180328115455_create_notifications.rb
new file mode 100644
index 0000000..c6be87e
--- /dev/null
+++ b/db/migrate/20180328115455_create_notifications.rb
@@ -0,0 +1,15 @@
+class CreateNotifications < ActiveRecord::Migration
+ def change
+ create_table :notifications do |t|
+ t.integer :notification_type
+ t.string :title
+ t.integer :level
+ t.text :body
+ t.boolean :dismissable
+ t.date :starts_at
+ t.date :expires_at
+
+ t.timestamps null: false
+ end
+ end
+end
diff --git a/db/migrate/20180405151713_rename_template_fields.rb b/db/migrate/20180405151713_rename_template_fields.rb
new file mode 100644
index 0000000..c4cc5e3
--- /dev/null
+++ b/db/migrate/20180405151713_rename_template_fields.rb
@@ -0,0 +1,11 @@
+class RenameTemplateFields < ActiveRecord::Migration
+ def up
+ rename_column :templates, :migrated, :archived
+ rename_column :templates, :dmptemplate_id, :family_id
+ end
+
+ def down
+ rename_column :templates, :archived, :migrated
+ rename_column :templates, :family_id, :dmptemplate_id
+ end
+end
diff --git a/db/migrate/20180405151942_remove_dirty_from_templates.rb b/db/migrate/20180405151942_remove_dirty_from_templates.rb
new file mode 100644
index 0000000..f77515e
--- /dev/null
+++ b/db/migrate/20180405151942_remove_dirty_from_templates.rb
@@ -0,0 +1,9 @@
+class RemoveDirtyFromTemplates < ActiveRecord::Migration
+ def up
+ remove_column :templates, :dirty
+ end
+
+ def down
+ add_column :templates, :dirty, :boolean, default: false
+ end
+end
diff --git a/db/migrate/20180405152454_add_family_id_index_to_templates.rb b/db/migrate/20180405152454_add_family_id_index_to_templates.rb
new file mode 100644
index 0000000..aee8a0c
--- /dev/null
+++ b/db/migrate/20180405152454_add_family_id_index_to_templates.rb
@@ -0,0 +1,9 @@
+class AddFamilyIdIndexToTemplates < ActiveRecord::Migration
+ def up
+ add_index :templates, :family_id
+ end
+
+ def down
+ remove_index :templates, :family_id
+ end
+end
diff --git a/db/migrate/20180412092647_create_notification_acknowledgements.rb b/db/migrate/20180412092647_create_notification_acknowledgements.rb
new file mode 100644
index 0000000..bbb06cf
--- /dev/null
+++ b/db/migrate/20180412092647_create_notification_acknowledgements.rb
@@ -0,0 +1,10 @@
+class CreateNotificationAcknowledgements < ActiveRecord::Migration
+ def change
+ create_table :notification_acknowledgements do |t|
+ t.belongs_to :user, foreign_key: true, index: true
+ t.belongs_to :notification, foreign_key: true, index: true
+
+ t.timestamps null: true
+ end
+ end
+end
diff --git a/db/migrate/20180417124026_add_unique_index_family_id_version_to_template.rb b/db/migrate/20180417124026_add_unique_index_family_id_version_to_template.rb
new file mode 100644
index 0000000..dac9d72
--- /dev/null
+++ b/db/migrate/20180417124026_add_unique_index_family_id_version_to_template.rb
@@ -0,0 +1,5 @@
+class AddUniqueIndexFamilyIdVersionToTemplate < ActiveRecord::Migration
+ def change
+ add_index(:templates, [:family_id, :version], unique: true)
+ end
+end
diff --git a/db/migrate/20180418115318_add_unique_index_customization_of_version_org_id_to_template.rb b/db/migrate/20180418115318_add_unique_index_customization_of_version_org_id_to_template.rb
new file mode 100644
index 0000000..0cb1bfd
--- /dev/null
+++ b/db/migrate/20180418115318_add_unique_index_customization_of_version_org_id_to_template.rb
@@ -0,0 +1,5 @@
+class AddUniqueIndexCustomizationOfVersionOrgIdToTemplate < ActiveRecord::Migration
+ def change
+ add_index(:templates, [:customization_of, :version, :org_id], unique: true)
+ end
+end
diff --git a/db/migrate/20180508151824_drop_tablename.rb b/db/migrate/20180508151824_drop_tablename.rb
new file mode 100644
index 0000000..e2cc6b8
--- /dev/null
+++ b/db/migrate/20180508151824_drop_tablename.rb
@@ -0,0 +1,5 @@
+class DropTablename < ActiveRecord::Migration
+ def change
+ drop_table :friendly_id_slugs
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index ca41822..a78eda1 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,10 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20180315161757) do
-
- # These are extensions that must be enabled in order to support this database
- enable_extension "plpgsql"
+ActiveRecord::Schema.define(version: 20180418115318) do
create_table "annotations", force: :cascade do |t|
t.integer "question_id"
@@ -80,7 +77,7 @@
create_table "friendly_id_slugs", force: :cascade do |t|
t.string "slug", null: false
t.integer "sluggable_id", null: false
- t.string "sluggable_type", limit: 40
+ t.string "sluggable_type"
t.datetime "created_at"
end
@@ -139,6 +136,28 @@
add_index "notes", ["answer_id"], name: "index_notes_on_answer_id"
+ create_table "notification_acknowledgements", force: :cascade do |t|
+ t.integer "user_id"
+ t.integer "notification_id"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "notification_acknowledgements", ["notification_id"], name: "index_notification_acknowledgements_on_notification_id"
+ add_index "notification_acknowledgements", ["user_id"], name: "index_notification_acknowledgements_on_user_id"
+
+ create_table "notifications", force: :cascade do |t|
+ t.integer "notification_type"
+ t.string "title"
+ t.integer "level"
+ t.text "body"
+ t.boolean "dismissable"
+ t.date "starts_at"
+ t.date "expires_at"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
create_table "org_identifiers", force: :cascade do |t|
t.string "identifier"
t.string "attrs"
@@ -339,13 +358,15 @@
t.integer "version"
t.integer "visibility"
t.integer "customization_of"
- t.integer "dmptemplate_id"
- t.boolean "migrated"
- t.boolean "dirty", default: false
+ t.integer "family_id"
+ t.boolean "archived"
t.text "links", default: "{\"funder\":[], \"sample_plan\":[]}"
end
- add_index "templates", ["org_id", "dmptemplate_id"], name: "template_organisation_dmptemplate_index"
+ add_index "templates", ["customization_of", "version", "org_id"], name: "index_templates_on_customization_of_and_version_and_org_id", unique: true
+ add_index "templates", ["family_id", "version"], name: "index_templates_on_family_id_and_version", unique: true
+ add_index "templates", ["family_id"], name: "index_templates_on_family_id"
+ add_index "templates", ["org_id", "family_id"], name: "template_organisation_dmptemplate_index"
add_index "templates", ["org_id"], name: "index_templates_on_org_id"
create_table "themes", force: :cascade do |t|
@@ -384,11 +405,11 @@
create_table "users", force: :cascade do |t|
t.string "firstname"
t.string "surname"
- t.string "email", default: "", null: false
+ t.string "email", default: "", null: false
t.string "orcid_id"
t.string "shibboleth_id"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
t.string "encrypted_password", default: ""
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
@@ -424,44 +445,5 @@
t.integer "perm_id"
end
- add_index "users_perms", ["user_id"], name: "index_users_perms_on_user_id"
-
- add_foreign_key "annotations", "orgs"
- add_foreign_key "annotations", "questions"
- add_foreign_key "answers", "plans"
- add_foreign_key "answers", "questions"
- add_foreign_key "answers", "users"
- add_foreign_key "answers_question_options", "answers"
- add_foreign_key "answers_question_options", "question_options"
- add_foreign_key "guidance_groups", "orgs"
- add_foreign_key "guidances", "guidance_groups"
- add_foreign_key "notes", "answers"
- add_foreign_key "notes", "users"
- add_foreign_key "org_identifiers", "identifier_schemes"
- add_foreign_key "org_identifiers", "orgs"
- add_foreign_key "org_token_permissions", "orgs"
- add_foreign_key "org_token_permissions", "token_permission_types"
- add_foreign_key "orgs", "languages"
- add_foreign_key "orgs", "regions"
- add_foreign_key "phases", "templates"
- add_foreign_key "plans", "templates"
- add_foreign_key "plans_guidance_groups", "guidance_groups"
- add_foreign_key "plans_guidance_groups", "plans"
- add_foreign_key "question_options", "questions"
- add_foreign_key "questions", "question_formats"
- add_foreign_key "questions", "sections"
- add_foreign_key "questions_themes", "questions"
- add_foreign_key "questions_themes", "themes"
- add_foreign_key "roles", "plans"
- add_foreign_key "roles", "users"
- add_foreign_key "sections", "phases"
- add_foreign_key "templates", "orgs"
- add_foreign_key "themes_in_guidance", "guidances"
- add_foreign_key "themes_in_guidance", "themes"
- add_foreign_key "user_identifiers", "identifier_schemes"
- add_foreign_key "user_identifiers", "users"
- add_foreign_key "users", "languages"
- add_foreign_key "users", "orgs"
- add_foreign_key "users_perms", "perms"
- add_foreign_key "users_perms", "users"
+ add_index "users_perms", ["user_id"], name: "index_users_perms_on_user_id", using: :btree
end
diff --git a/db/seeds.rb b/db/seeds.rb
index 6257841..f41156e 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -5,8 +5,8 @@
# Identifier Schemes
# -------------------------------------------------------
identifier_schemes = [
- {name: 'orcid', description: 'ORCID', active: true,
- logo_url:'http://orcid.org/sites/default/files/images/orcid_16x16.png',
+ {name: 'orcid', description: 'ORCID', active: true,
+ logo_url:'http://orcid.org/sites/default/files/images/orcid_16x16.png',
user_landing_url:'https://orcid.org' },
{name: 'shibboleth', description: 'Your institutional credentials', active: true,
},
@@ -57,7 +57,7 @@
Dir.entries("#{Rails.root.join("config", "locales").to_s}").each do |f|
if f[-4..-1] == '.yml'
lang = f.gsub('.yml', '')
-
+
if Language.where(abbreviation: lang).empty?
Language.create!({
abbreviation: lang,
@@ -72,10 +72,10 @@
# Regions (create the super regions first and then create the rest)
# -------------------------------------------------------
regions = [
- {abbreviation: 'horizon',
+ {abbreviation: 'horizon',
description: 'European super region',
name: 'Horizon2020',
-
+
sub_regions: [
{abbreviation: 'uk',
description: 'United Kingdom',
@@ -90,7 +90,7 @@
description: 'Spain',
name: 'ES'}
]},
- {abbreviation: 'us',
+ {abbreviation: 'us',
description: 'United States of America',
name: 'US'}
]
@@ -99,9 +99,9 @@
regions.each do |r|
srs = r[:sub_regions]
r.delete(:sub_regions) unless r[:sub_regions].nil?
-
+
if Region.find_by(abbreviation: r[:abbreviation]).nil?
- region = Region.create!(r)
+ region = Region.create!(r)
unless srs.nil?
srs.each do |sr|
@@ -111,7 +111,7 @@
end
end
end
-
+
end
end
@@ -179,7 +179,7 @@
]
orgs.map{ |o| Org.create!(o) if Org.find_by(abbreviation: o[:abbreviation]).nil? }
-# Create a Super Admin associated with our generic organisation,
+# Create a Super Admin associated with our generic organisation,
# an Org Admin for our funder and an Org Admin and User for our University
# -------------------------------------------------------
users = [
@@ -229,7 +229,7 @@
users.map{ |u| User.create!(u) if User.find_by(email: u[:email]).nil? }
# Create a Guidance Group for our organisation and the funder
-# -------------------------------------------------------
+# -------------------------------------------------------
guidance_groups = [
{name: "Generic Guidance (provided by the example curation centre)",
org: Org.find_by(abbreviation: Rails.configuration.branding[:organisation][:abbreviation]),
@@ -243,17 +243,17 @@
guidance_groups.map{ |gg| GuidanceGroup.create!(gg) if GuidanceGroup.find_by(name: gg[:name]).nil? }
# Initialize with the generic Roadmap guidance and a sample funder guidance
-# -------------------------------------------------------
+# -------------------------------------------------------
guidances = [
{text: "● Give a summary of the data you will collect or create, noting the content, coverage and data type, e.g., tabular data, survey data, experimental measurements, models, software, audiovisual data, physical samples, etc.
-● Consider how your data could complement and integrate with existing data, or whether there are any existing data or methods that you could reuse.
+● Consider how your data could complement and integrate with existing data, or whether there are any existing data or methods that you could reuse.
● If purchasing or reusing existing data, explain how issues such as copyright and IPR have been addressed. You should aim to m
inimise any restrictions on the reuse (and subsequent sharing) of third-party data.",
guidance_group: GuidanceGroup.first,
published: true,
themes: [Theme.find_by(title: 'Data Description')]},
- {text: "● Clearly note what format(s) your data will be in, e.g., plain text (.txt), comma-separated values (.csv), geo-referenced TIFF (.tif, .tfw).
-● Explain why you have chosen certain formats. Decisions may be based on staff expertise, a preference for open formats, the standards accepted by data centres or widespread usage within a given community.
+ {text: "● Clearly note what format(s) your data will be in, e.g., plain text (.txt), comma-separated values (.csv), geo-referenced TIFF (.tif, .tfw).
+● Explain why you have chosen certain formats. Decisions may be based on staff expertise, a preference for open formats, the standards accepted by data centres or widespread usage within a given community.
● Using standardised, interchangeable or open formats ensures the long-term usability of data; these are recommended for sharing and archiving.
● See UK Data Service guidance on recommended formats or DataONE Best Practices for file formats ",
guidance_group: GuidanceGroup.first,
@@ -265,9 +265,9 @@
guidance_group: GuidanceGroup.first,
published: true,
themes: [Theme.find_by(title: 'Data Volume')]},
- {text: "● Outline how the data will be collected and processed. This should cover relevant standards or methods, quality assurance and data organisation.
+ {text: "● Outline how the data will be collected and processed. This should cover relevant standards or methods, quality assurance and data organisation.
● Indicate how the data will be organised during the project, mentioning, e.g., naming conventions, version control and folder structures. Consistent, well-ordered research data will be easier to find, understand and reuse
-● Explain how the consistency and quality of data collection will be controlled and documented. This may include processes such as calibration, repeat samples or measurements, standardised data capture, data entry validation, peer review of data or representation with controlled vocabularies.
+● Explain how the consistency and quality of data collection will be controlled and documented. This may include processes such as calibration, repeat samples or measurements, standardised data capture, data entry validation, peer review of data or representation with controlled vocabularies.
● See the DataOne Best Practices for data quality ",
guidance_group: GuidanceGroup.first,
published: true,
@@ -287,23 +287,23 @@
guidance_group: GuidanceGroup.first,
published: true,
themes: [Theme.find_by(title: 'Ethics & Privacy')]},
- {text: "● State who will own the copyright and IPR of any new data that you will generate. For multi-partner projects, IPR ownership should be covered in the consortium agreement.
-● Outline any restrictions needed on data sharing, e.g., to protect proprietary or patentable data.
+ {text: "● State who will own the copyright and IPR of any new data that you will generate. For multi-partner projects, IPR ownership should be covered in the consortium agreement.
+● Outline any restrictions needed on data sharing, e.g., to protect proprietary or patentable data.
● Explain how the data will be licensed for reuse. See the DCC guide on How to license research data and EUDAT’s data and software licensing wizard .",
guidance_group: GuidanceGroup.first,
published: true,
themes: [Theme.find_by(title: 'Intellectual Property Rights')]},
{text: "● Describe where the data will be stored and backed up during the course of research activities. This may vary if you are doing fieldwork or working across multiple sites so explain each procedure.
-● Identify who will be responsible for backup and how often this will be performed. The use of robust, managed storage with automatic backup, for example, that provided by university IT teams, is preferable. Storing data on laptops, computer hard drives or external storage devices alone is very risky.
+● Identify who will be responsible for backup and how often this will be performed. The use of robust, managed storage with automatic backup, for example, that provided by university IT teams, is preferable. Storing data on laptops, computer hard drives or external storage devices alone is very risky.
● See UK Data Service Guidance on data storage or DataONE Best Practices for storage
-● Also consider data security, particularly if your data is sensitive e.g., detailed personal data, politically sensitive information or trade secrets. Note the main risks and how these will be managed.
+● Also consider data security, particularly if your data is sensitive e.g., detailed personal data, politically sensitive information or trade secrets. Note the main risks and how these will be managed.
● Identify any formal standards that you will comply with, e.g., ISO 27001. See the DCC Briefing Paper on Information Security Management -ISO 27000 and UK Data Service guidance on data security ",
guidance_group: GuidanceGroup.first,
published: true,
themes: [Theme.find_by(title: 'Storage & Security')]},
- {text: "● How will you share the data e.g. deposit in a data repository, use a secure data service, handle data requests directly or use another mechanism? The methods used will depend on a number of factors such as the type, size, complexity and sensitivity of the data.
-● When will you make the data available? Research funders expect timely release. They typically allow embargoes but not prolonged exclusive use.
-● Who will be able to use your data? If you need to restricted access to certain communities or apply data sharing agreements, explain why.
+ {text: "● How will you share the data e.g. deposit in a data repository, use a secure data service, handle data requests directly or use another mechanism? The methods used will depend on a number of factors such as the type, size, complexity and sensitivity of the data.
+● When will you make the data available? Research funders expect timely release. They typically allow embargoes but not prolonged exclusive use.
+● Who will be able to use your data? If you need to restricted access to certain communities or apply data sharing agreements, explain why.
● Consider strategies to minimise restrictions on sharing. These may include anonymising or aggregating data, gaining participant consent for data sharing, gaining copyright permissions, and agreeing a limited embargo period.
● How might your data be reused in other contexts? Where there is potential for reuse, you should use standards and formats that facilitate this, and ensure that appropriate metadata is available online so your data can be discovered. Persistent identifiers should be applied so people can reliably and efficiently find your data. They also help you to track citations and reuse.",
guidance_group: GuidanceGroup.first,
@@ -321,19 +321,19 @@
guidance_group: GuidanceGroup.first,
published: true,
themes: [Theme.find_by(title: 'Preservation')]},
- {text: "● Outline the roles and responsibilities for all activities, e.g., data capture, metadata production, data quality, storage and backup, data archiving & data sharing. Individuals should be named where possible.
+ {text: "● Outline the roles and responsibilities for all activities, e.g., data capture, metadata production, data quality, storage and backup, data archiving & data sharing. Individuals should be named where possible.
● For collaborative projects you should explain the coordination of data management responsibilities across partners.
● See UK Data Service guidance on data management roles and responsibilities or DataONE Best Practices: Define roles and assign responsibilities for data management ",
guidance_group: GuidanceGroup.first,
published: true,
themes: [Theme.find_by(title: 'Roles & Responsibilities')]},
{text: "● Carefully consider and justify any resources needed to deliver the plan. These may include storage costs, hardware, staff time, costs of preparing data for deposit and repository charges.
-● Outline any relevant technical expertise, support and training that is likely to be required and how it will be acquired.
+● Outline any relevant technical expertise, support and training that is likely to be required and how it will be acquired.
● If you are not depositing in a data repository, ensure you have appropriate resources and systems in place to share and preserve the data. See UK Data Service guidance on costing data management ",
guidance_group: GuidanceGroup.first,
published: true,
themes: [Theme.find_by(title: 'Budget')]},
- {text: "● Consider whether there are any existing procedures that you can base your approach on. If your group/department has local guidelines that you work to, point to them here.
+ {text: "● Consider whether there are any existing procedures that you can base your approach on. If your group/department has local guidelines that you work to, point to them here.
● List any other relevant funder, institutional, departmental or group policies on data management, data sharing and data security. ",
guidance_group: GuidanceGroup.first,
published: true,
@@ -346,7 +346,7 @@
guidances.map{ |g| Guidance.create!(g) if Guidance.find_by(text: g[:text]).nil? }
# Create a default template for the curation centre and one for the example funder
-# -------------------------------------------------------
+# -------------------------------------------------------
templates = [
{title: "My Curation Center's Default Template",
description: "The default template",
@@ -358,7 +358,7 @@
dmptemplate_id: 1,
visibility: Template.visibilities[:publicly_visible],
links: {"funder":[],"sample_plan":[]}},
-
+
{title: "OLD - Department of Testing Award",
published: false,
org: Org.find_by(abbreviation: 'GA'),
@@ -368,7 +368,7 @@
visibility: Template.visibilities[:organisationally_visible],
dmptemplate_id: 2,
links: {"funder":[],"sample_plan":[]}},
-
+
{title: "Department of Testing Award",
published: true,
org: Org.find_by(abbreviation: 'GA'),
@@ -379,11 +379,11 @@
dmptemplate_id: 3,
links: {"funder":[],"sample_plan":[]}}
]
-# Template creation calls defaults handler which sets is_default and
+# Template creation calls defaults handler which sets is_default and
# published to false automatically, so update them after creation
-templates.map do |t|
- if Template.find_by(title: t[:title]).nil?
- tmplt = Template.create!(t)
+templates.map do |t|
+ if Template.find_by(title: t[:title]).nil?
+ tmplt = Template.create!(t)
tmplt.published = t[:published]
tmplt.is_default = t[:is_default]
tmplt.visibility = t[:visibility]
@@ -392,18 +392,18 @@
end
# Create 2 phases for the funder's template and one for our generic template
-# -------------------------------------------------------
+# -------------------------------------------------------
phases = [
{title: "Generic Data Management Planning Template",
number: 1,
modifiable: false,
template: Template.find_by(title: "My Curation Center's Default Template")},
-
+
{title: "Detailed Overview",
number: 1,
modifiable: false,
template: Template.find_by(title: "OLD - Department of Testing Award")},
-
+
{title: "Preliminary Statement of Work",
number: 1,
modifiable: true,
@@ -420,7 +420,7 @@
funder_template_phase_2 = Phase.find_by(title: "Detailed Overview")
# Create sections for the 2 templates and their phases
-# -------------------------------------------------------
+# -------------------------------------------------------
sections = [
# Sections for the Generic Template
{title: "Data Collection",
@@ -464,7 +464,7 @@
number: 1,
published: false,
modifiable: true,
- phase: Phase.find_by(title: "Detailed Overview")},
+ phase: Phase.find_by(title: "Detailed Overview")},
# Sections for the Funder Template's Preliminary Phase
{title: "Data Overview",
@@ -510,7 +510,7 @@
text_area = QuestionFormat.find_by(title: "Text area")
# Create questions for the 2 templates and their phases
-# -------------------------------------------------------
+# -------------------------------------------------------
questions = [
# Questions for the Generic Template
{text: "What data will you collect or create?",
@@ -588,7 +588,7 @@
modifiable: false,
section: Section.find_by(title: "Responsibilities and Resources"),
question_format: text_area},
-
+
# Questions for old version of Funder Template
{text: "What data will you collect and how will it be obtained?",
number: 1,
@@ -600,7 +600,7 @@
modifiable: false,
section: Section.find_by(title: "Data Collection and Preservation"),
question_format: text_area},
-
+
# Questions for the Funder Template's Preliminary Phase
{text: "Provide an overview of the dataset.",
number: 1,
@@ -620,7 +620,7 @@
section: Section.find_by(title: "Data Description"),
question_format: text_area,
themes: [Theme.find_by(title: "Data Collection")]},
-
+
# Questions for the Funder Template's Detailed Phase
{text: "What is your policy for long term access to your dataset?",
number: 1,
@@ -689,11 +689,11 @@
questions.map{ |q| Question.create!(q) if Question.find_by(text: q[:text]).nil? }
drop_down_question = Question.find_by(text: "Where will you store your data during the research period?")
-multi_select_question = Question.find_by(text: "What type(s) of data will you collect?")
+multi_select_question = Question.find_by(text: "What type(s) of data will you collect?")
radio_button_question = Question.find_by(text: "Please select the appropriate formats.")
# Create suggested answers for a few questions
-# -------------------------------------------------------
+# -------------------------------------------------------
annotations = [
{text: "We will preserve it in Dryad or a similar data repository service.",
type: Annotation.types[:example_answer],
@@ -707,7 +707,7 @@
annotations.map{ |s| Annotation.create!(s) if Annotation.find_by(text: s[:text]).nil? }
# Create options for the dropdown, multi-select and radio buttons
-# -------------------------------------------------------
+# -------------------------------------------------------
question_options = [
{text: "csv files",
number: 1,
@@ -721,7 +721,7 @@
number: 3,
question: radio_button_question,
is_default: false},
-
+
{text: "local hard drive",
number: 1,
question: drop_down_question,
@@ -734,7 +734,7 @@
number: 3,
question: drop_down_question,
is_default: false},
-
+
{text: "statistical",
number: 1,
question: multi_select_question,
@@ -755,7 +755,7 @@
question_options.map{ |q| QuestionOption.create!(q) if QuestionOption.find_by(text: q[:text]).nil? }
# Create plans
-# -------------------------------------------------------
+# -------------------------------------------------------
=begin
plans = [
{title: "Sample plan",
@@ -787,7 +787,7 @@
plan: plan,
user: user,
question: Question.find_by(text: "How will you store the data and how will it be preserved?")},
-
+
{text: "We want people to be able to access it. ",
plan: plan,
user: user,
@@ -799,7 +799,7 @@
{plan: plan,
user: user,
question: multi_select_question,
- question_options: [QuestionOption.find_by(text: "image/video"),
+ question_options: [QuestionOption.find_by(text: "image/video"),
QuestionOption.find_by(text: "other")]},
{plan: plan,
user: user,
diff --git a/lib/assets/javascripts/application.js b/lib/assets/javascripts/application.js
index 17f32e2..196a5ee 100644
--- a/lib/assets/javascripts/application.js
+++ b/lib/assets/javascripts/application.js
@@ -10,8 +10,6 @@
// Page specific JS
import './views/answers/edit';
import './views/answers/rda_metadata';
-import './views/annotations/add';
-import './views/annotations/edit';
import './views/contacts/new';
import './views/devise/invitations/edit';
import './views/devise/passwords/edit';
@@ -21,26 +19,22 @@
import './views/guidance_groups/admin_new';
import './views/guidances/new_edit';
import './views/notes/index';
+import './views/org_admin/phases/new_edit';
+import './views/org_admin/phases/preview';
+import './views/org_admin/question_options/index';
+import './views/org_admin/questions/sharedEventHandlers';
+import './views/org_admin/sections/index';
import './views/org_admin/templates/edit';
import './views/org_admin/templates/index';
-import './views/org_admin/templates/show';
+import './views/org_admin/templates/new';
import './views/orgs/admin_edit';
import './views/orgs/shibboleth_ds';
-import './views/phases/edit';
-import './views/phases/show';
import './views/plans/download';
import './views/plans/edit_details';
import './views/plans/index';
import './views/plans/new';
import './views/plans/share';
import './views/roles/edit';
-import './views/sections/edit';
-import './views/sections/index';
-import './views/sections/new';
-import './views/questions/new_edit';
-import './views/questions/index';
-import './views/questions/show';
-import './views/question_options/index';
import './views/shared/create_account_form';
import './views/shared/my_org';
import './views/shared/sign_in_form';
@@ -49,3 +43,4 @@
import './views/usage/index';
import './views/users/notification_preferences';
import './views/users/admin_grant_permissions';
+import './views/super_admin/notifications/edit';
diff --git a/lib/assets/javascripts/utils/ariatiseForm.js b/lib/assets/javascripts/utils/ariatiseForm.js
index aae08c9..b9a9ad2 100644
--- a/lib/assets/javascripts/utils/ariatiseForm.js
+++ b/lib/assets/javascripts/utils/ariatiseForm.js
@@ -207,6 +207,7 @@
// Bind validations to the form's submit button
$(`${options.selector}`).submit((e) => {
let anyInvalid = false;
+ let firstInvalid;
validatable.each((i, el) => {
const type = getValidationTypeForElement(el);
const required = ($(el).attr('aria-required') && $(el).attr('aria-required') === 'true');
@@ -218,11 +219,18 @@
} else {
anyInvalid = true;
invalid(el);
+ if (!isObject(firstInvalid)) {
+ firstInvalid = el;
+ }
}
}
});
if (anyInvalid) {
e.preventDefault();
+ // Set focus on the first invalid input
+ if (isObject(firstInvalid)) {
+ firstInvalid.focus();
+ }
}
});
}
diff --git a/lib/assets/javascripts/utils/expandCollapseAll.js b/lib/assets/javascripts/utils/expandCollapseAll.js
index f779915..5e88627 100644
--- a/lib/assets/javascripts/utils/expandCollapseAll.js
+++ b/lib/assets/javascripts/utils/expandCollapseAll.js
@@ -45,7 +45,13 @@
const panelCollapse = $(el);
// Expands or collapses the panel according to the
// direction passed (e.g. show --> expands, hide --> collapses)
- $(el).collapse(direction);
+ if (direction === 'show') {
+ if (!panelCollapse.hasClass('in')) {
+ panelCollapse.prev().trigger('click');
+ }
+ } else {
+ panelCollapse.collapse(direction);
+ }
// Sets icon at panel-title accordingly
panelCollapse.prev().find('i.fa')
.removeClass('fa-plus fa-minus').addClass(direction === 'show' ? 'fa-minus' : 'fa-plus');
diff --git a/lib/assets/javascripts/utils/validation.js b/lib/assets/javascripts/utils/validation.js
index 0fdf521..df50fbf 100644
--- a/lib/assets/javascripts/utils/validation.js
+++ b/lib/assets/javascripts/utils/validation.js
@@ -223,6 +223,7 @@
export const validate = (ctx) => {
let anyInvalid = false;
+ let firstInvalid;
if (isObject(ctx)) {
if ($(ctx).is('input')) {
anyInvalid = !checkValidations(ctx);
@@ -230,8 +231,15 @@
validatableFields(ctx).each((i, el) => {
if (!checkValidations(el)) {
anyInvalid = true;
+ if (!isObject(firstInvalid)) {
+ firstInvalid = el;
+ }
}
});
+ // Set focus on the first invalid input
+ if (isObject(firstInvalid)) {
+ firstInvalid.focus();
+ }
}
}
return !anyInvalid;
diff --git a/lib/assets/javascripts/views/annotations/add.js b/lib/assets/javascripts/views/annotations/add.js
deleted file mode 100644
index 498c8f5..0000000
--- a/lib/assets/javascripts/views/annotations/add.js
+++ /dev/null
@@ -1,9 +0,0 @@
-$(() => {
- $('.cancel_add_annotations').on('click', (e) => {
- e.preventDefault();
- const target = $(e.target).attr('href');
- $(target).hide();
- $(target).closest('.col-md-12').find('.add_annotations_button').show();
- $(target).closest('.col-md-12').find('.show_annotations_div').show();
- });
-});
diff --git a/lib/assets/javascripts/views/annotations/edit.js b/lib/assets/javascripts/views/annotations/edit.js
deleted file mode 100644
index 0884ed9..0000000
--- a/lib/assets/javascripts/views/annotations/edit.js
+++ /dev/null
@@ -1,9 +0,0 @@
-$(() => {
- $('.cancel_edit_annotations').on('click', (e) => {
- e.preventDefault();
- const target = $(e.target).attr('href');
- $(target).hide();
- $(target).closest('.col-md-12').find('.edit_annotations_button').show();
- $(target).closest('.col-md-12').find('.show_annotations_div').show();
- });
-});
diff --git a/lib/assets/javascripts/views/org_admin/phases/new_edit.js b/lib/assets/javascripts/views/org_admin/phases/new_edit.js
new file mode 100644
index 0000000..9e85c68
--- /dev/null
+++ b/lib/assets/javascripts/views/org_admin/phases/new_edit.js
@@ -0,0 +1,121 @@
+import 'bootstrap-sass/assets/javascripts/bootstrap/collapse';
+import { Tinymce } from '../../../utils/tinymce';
+import { isObject, isString } from '../../../utils/isType';
+import getConstant from '../../../constants';
+import expandCollapseAll from '../../../utils/expandCollapseAll';
+import ariatiseForm from '../../../utils/ariatiseForm';
+
+import onChangeQuestionFormat from '../questions/sharedEventHandlers';
+import initQuestionOption from '../question_options/index';
+
+$(() => {
+ // Attach handlers for the expand/collapse all accordions
+ expandCollapseAll();
+
+ Tinymce.init({ selector: '.phase' });
+ ariatiseForm({ selector: '.phase_form' });
+ const parentSelector = '#sections_accordion';
+
+ const initQuestion = (context) => {
+ const target = $(context);
+ if (isObject(target)) {
+ Tinymce.init({ selector: `#${context} .question` });
+ ariatiseForm({ selector: `#${context} .question_form` });
+ initQuestionOption(context);
+ // Swap in the question_formats when the user selects an option based question type
+ $(`#${context} select.question_format`).change((e) => {
+ onChangeQuestionFormat(e);
+ });
+ }
+ };
+ const getQuestionPanel = (target) => {
+ let panelBody;
+ if (isObject(target)) {
+ panelBody = target.closest('.question_container');
+ if (!isObject(panelBody) || !isString(panelBody.attr('id'))) {
+ panelBody = target.closest('.panel-body').find('.new-question');
+ }
+ }
+ return panelBody;
+ };
+ const initSection = (selector) => {
+ if (isString(selector)) {
+ // Wire up the section and its Questions
+ Tinymce.init({ selector: `${selector} .section` });
+ ariatiseForm({ selector: `${selector} .section_form` });
+
+ const questionForm = $(selector).find('.question_form');
+ if (questionForm.length > 0) {
+ // Load Tinymce when the 'show' form has a question form.
+ // ONLY applicable for template customizations
+ Tinymce.init({ selector: `${selector} .question_form .question` });
+ }
+ }
+ };
+
+ // Attach handlers for the Section expansion
+ $(parentSelector).on('ajax:before', 'a.ajaxified-section[data-remote="true"]', (e) => {
+ const panelBody = $(e.target).parent().find('.panel-body');
+ return panelBody.attr('data-loaded') === 'false';
+ });
+ $(parentSelector).on('ajax:success', 'a.ajaxified-section[data-remote="true"]', (e, data) => {
+ const panelBody = $(e.target).parent().find('.panel-body');
+ const panel = panelBody.parent();
+ if (isObject(panelBody)) {
+ // Display the section's html
+ panelBody.attr('data-loaded', 'true');
+ panelBody.html(data);
+ // Wire up the section
+ initSection(`#${panel.attr('id')}`);
+ }
+ });
+
+ // Attach handlers for the Question show/edit/new
+ $(parentSelector).on('ajax:before', 'a.ajaxified-question[data-remote="true"]', (e) => {
+ const panelBody = getQuestionPanel($(e.target));
+ if (isObject(panelBody)) {
+ // Release any Tinymce editors that have been loaded
+ panelBody.find('.question').each((idx, el) => {
+ Tinymce.destroyEditorById($(el).attr('id'));
+ });
+ }
+ });
+ $(parentSelector).on('ajax:success', 'a.ajaxified-question[data-remote="true"]', (e, data) => {
+ const target = $(e.target);
+ const panelBody = getQuestionPanel(target);
+ if (isObject(panelBody)) {
+ const id = panelBody.attr('id');
+ // Display the section's html
+ panelBody.html(data);
+ initQuestion(id);
+ if (panelBody.is('.new-question')) {
+ target.hide();
+ }
+ }
+ });
+ $(parentSelector).on('ajax:error', 'a.ajaxified-question[data-remote="true"]', (e) => {
+ const panelBody = getQuestionPanel($(e.target));
+ if (isObject(panelBody)) {
+ panelBody.html(`${getConstant('AJAX_UNABLE_TO_LOAD_TEMPLATE_SECTION')}
`);
+ }
+ });
+ // When we cancel the new question we just remove the form and its Tinymce editors
+ $(parentSelector).on('click', '.cancel-new-question', (e) => {
+ e.preventDefault();
+ const target = $(e.target);
+ const panel = target.closest('.question_container');
+ panel.find('.question').each((idx, el) => {
+ Tinymce.destroyEditorById($(el).attr('id'));
+ });
+ panel.html('');
+ panel.closest('.panel-body').find('.new-question-button a.ajaxified-question[data-remote="true"]').show();
+ });
+
+ // Handle the section that has focus on initial page load
+ const currentSection = $('#sections_accordion .in');
+ if (currentSection.length > 0) {
+ initSection(`#${currentSection.attr('id')}`);
+ }
+ // Handle the new section
+ initSection('#new_section_new_section');
+});
diff --git a/lib/assets/javascripts/views/org_admin/phases/preview.js b/lib/assets/javascripts/views/org_admin/phases/preview.js
new file mode 100644
index 0000000..9ccc465
--- /dev/null
+++ b/lib/assets/javascripts/views/org_admin/phases/preview.js
@@ -0,0 +1,5 @@
+$(() => {
+ $('.preview-tab').click((e) => {
+ e.preventDefault();
+ });
+});
diff --git a/lib/assets/javascripts/views/org_admin/question_options/index.js b/lib/assets/javascripts/views/org_admin/question_options/index.js
new file mode 100644
index 0000000..0b939b9
--- /dev/null
+++ b/lib/assets/javascripts/views/org_admin/question_options/index.js
@@ -0,0 +1,34 @@
+export default (context) => {
+ $(`#${context} .delete_question_option`).on('click', (e) => {
+ e.preventDefault();
+ const source = $(e.target).closest('[data-attribute="question_option"]');
+ source.find('.destroy-question-option').val(true);
+ source.hide();
+ // $(source).closest('[data-attribute="question_option"]').remove();
+ });
+ $(`#${context} .new_question_option`).on('click', (e) => {
+ e.preventDefault();
+ const source = e.target;
+ const last = $(source).closest('[data-attribute="question_options"]').find('[data-attribute="question_option"]').last();
+ const cloned = last.clone(true);
+ const array = $(cloned).find('[id$="_number"]').prop('id').match(/_[\d]_+/);
+ if (array) {
+ const index = Number(array[0].replace(/_/g, ''));
+ // Reset values for the new cloned inputs
+ cloned.find('[id$="_number"]').val(index + 2);
+ cloned.find('[id$="_text"]').val('');
+ cloned.find('[id$="_is_default"]').prop('checked', false);
+ cloned.find('[id$="__destroy"]').val(false);
+ cloned.find('input').each((i, el) => {
+ const target = $(el);
+ const id = target.prop('id').replace(/_[\d]+_/g, `_${index + 1}_`);
+ const name = target.prop('name').replace(/\[[\d]+\]/g, `[${index + 1}]`);
+ target.prop('id', id);
+ target.prop('name', name);
+ });
+ last.after(cloned);
+ cloned.show();
+ }
+ });
+};
+
diff --git a/lib/assets/javascripts/views/org_admin/questions/sharedEventHandlers.js b/lib/assets/javascripts/views/org_admin/questions/sharedEventHandlers.js
new file mode 100644
index 0000000..484dece
--- /dev/null
+++ b/lib/assets/javascripts/views/org_admin/questions/sharedEventHandlers.js
@@ -0,0 +1,40 @@
+const onChangeQuestionFormat = (e) => {
+ const source = e.target;
+ const selected = source.value;
+ const defaultValue = $(source).closest('form').find('[data-attribute="default_value"]');
+ const questionOptions = $(source).closest('form').find('[data-attribute="question_options"]');
+ const opComment = $(source).closest('form').find('[data-attribute="option_comment"]');
+ switch (selected) {
+ case '1':
+ questionOptions.hide();
+ opComment.hide();
+ defaultValue.show();
+ defaultValue.find('[data-attribute="textfield"]').hide();
+ defaultValue.find('[data-attribute="textarea"]').show();
+ break;
+ case '2':
+ questionOptions.hide();
+ opComment.hide();
+ defaultValue.show();
+ defaultValue.find('[data-attribute="textarea"]').hide();
+ defaultValue.find('[data-attribute="textfield"]').show();
+ break;
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ defaultValue.hide();
+ questionOptions.show();
+ opComment.show();
+ break;
+ case '7':
+ defaultValue.hide();
+ questionOptions.hide();
+ opComment.show();
+ break;
+ default :
+ break;
+ }
+};
+
+export { onChangeQuestionFormat as default };
diff --git a/lib/assets/javascripts/views/org_admin/sections/index.js b/lib/assets/javascripts/views/org_admin/sections/index.js
new file mode 100644
index 0000000..c96ed30
--- /dev/null
+++ b/lib/assets/javascripts/views/org_admin/sections/index.js
@@ -0,0 +1,9 @@
+import ariatiseForm from '../../../utils/ariatiseForm';
+
+$(() => {
+ ariatiseForm({ selector: '.new_section' });
+ $('.section_new_link').on('click', (e) => {
+ $(e.target).hide();
+ $(e.target).closest('.row').find('.section_new').show();
+ });
+});
diff --git a/lib/assets/javascripts/views/org_admin/templates/edit.js b/lib/assets/javascripts/views/org_admin/templates/edit.js
index f1a8452..8c759ab 100644
--- a/lib/assets/javascripts/views/org_admin/templates/edit.js
+++ b/lib/assets/javascripts/views/org_admin/templates/edit.js
@@ -8,11 +8,6 @@
$(() => {
Tinymce.init({ selector: '.template' });
enableValidations($('.edit_template'));
- $('.template_show_link').on('click', (e) => {
- e.preventDefault();
- $(e.target).closest('.template_edit').hide();
- $(e.target).closest('.tab-pane').find('.template_show').show();
- });
$('.edit_template').on('ajax:before', (e) => {
const links = {};
eachLinks((ctx, value) => {
diff --git a/lib/assets/javascripts/views/org_admin/templates/index.js b/lib/assets/javascripts/views/org_admin/templates/index.js
index c60f8cc..aeaf252 100644
--- a/lib/assets/javascripts/views/org_admin/templates/index.js
+++ b/lib/assets/javascripts/views/org_admin/templates/index.js
@@ -1,6 +1,6 @@
$(() => {
// Update the contents of the table when user clicks on a scope link
$('.template-scope').on('ajax:success', 'a[data-remote="true"]', (e, data) => {
- $(e.target).closest('.paginable').html(data);
+ $(e.target).closest('.template-scope').find('.paginable').html(data);
});
});
diff --git a/lib/assets/javascripts/views/org_admin/templates/new.js b/lib/assets/javascripts/views/org_admin/templates/new.js
new file mode 100644
index 0000000..19dc3ab
--- /dev/null
+++ b/lib/assets/javascripts/views/org_admin/templates/new.js
@@ -0,0 +1,19 @@
+import { Tinymce } from '../../../utils/tinymce';
+import { enableValidations, validate } from '../../../utils/validation';
+import { eachLinks } from '../../../utils/links';
+
+$(() => {
+ Tinymce.init({ selector: '.template' });
+ enableValidations($('.new_template'));
+ $('.new_template').on('submit', (e) => {
+ const links = {};
+ eachLinks((ctx, value) => {
+ links[ctx] = value;
+ }).done(() => {
+ $('#template-links').val(JSON.stringify(links));
+ });
+ if (!validate(e.target)) {
+ e.preventDefault();
+ }
+ });
+});
diff --git a/lib/assets/javascripts/views/org_admin/templates/show.js b/lib/assets/javascripts/views/org_admin/templates/show.js
deleted file mode 100644
index fd89a07..0000000
--- a/lib/assets/javascripts/views/org_admin/templates/show.js
+++ /dev/null
@@ -1,7 +0,0 @@
-$(() => {
- $('.template_edit_link').on('click', (e) => {
- e.preventDefault();
- $(e.target).closest('.template_show').hide();
- $(e.target).closest('.tab-pane').find('.template_edit').show();
- });
-});
diff --git a/lib/assets/javascripts/views/phases/edit.js b/lib/assets/javascripts/views/phases/edit.js
deleted file mode 100644
index d3bbefd..0000000
--- a/lib/assets/javascripts/views/phases/edit.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import 'bootstrap-sass/assets/javascripts/bootstrap/collapse';
-import expandCollapseAll from '../../utils/expandCollapseAll';
-import { Tinymce } from '../../utils/tinymce';
-
-$(() => {
- // Attach handlers for the expand/collapse all accordions
- expandCollapseAll();
- Tinymce.init({ selector: '.phase' });
- $('.phase_show_link').on('click', (e) => {
- e.preventDefault();
- $(e.target).closest('.phase_edit').hide();
- $(e.target).closest('.tab-pane').find('.phase_show').show();
- });
-});
diff --git a/lib/assets/javascripts/views/phases/show.js b/lib/assets/javascripts/views/phases/show.js
deleted file mode 100644
index a4c160f..0000000
--- a/lib/assets/javascripts/views/phases/show.js
+++ /dev/null
@@ -1,7 +0,0 @@
-$(() => {
- $('.phase_edit_link').on('click', (e) => {
- e.preventDefault();
- $(e.target).closest('.phase_show').hide();
- $(e.target).closest('.tab-pane').find('.phase_edit').show();
- });
-});
diff --git a/lib/assets/javascripts/views/question_options/index.js b/lib/assets/javascripts/views/question_options/index.js
deleted file mode 100644
index fbbfc9f..0000000
--- a/lib/assets/javascripts/views/question_options/index.js
+++ /dev/null
@@ -1,30 +0,0 @@
-$(() => {
- $('.delete_question_option').on('click', (e) => {
- e.preventDefault();
- const source = e.target;
- $(source).closest('[data-attribute="question_option"]').hide();
- });
- $('.new_question_option').on('click', (e) => {
- e.preventDefault();
- const source = e.target;
- const last = $(source).closest('[data-attribute="question_options"]').find('[data-attribute="question_option"]').last();
- const cloned = last.clone(true);
- const array = $(cloned).find('[id$="_number"]').prop('id').match(/[^\d]*(\d)+[^$]*/);
- if (array) {
- const index = Number(array[1]);
- // Reset values for the new cloned inputs
- cloned.find(`[id$="${index}_number"]`).val(index + 2);
- cloned.find(`[id$=${index}_text]`).val('');
- cloned.find(`[id$=${index}_is_default]`).prop('checked', false);
- cloned.find(`[id$="${index}__destroy"]`).val(false);
- cloned.find('input').each((i, el) => {
- // Rename id and name for the cloned inputs
- $(el).prop('id', $(el).prop('id').replace(/_\d+_/g, `_${index + 1}_`));
- $(el).prop('name', $(el).prop('name').replace(/\[\d+\]/g, `[${index + 1}]`));
- });
- last.after(cloned);
- cloned.show();
- }
- });
-});
-
diff --git a/lib/assets/javascripts/views/questions/index.js b/lib/assets/javascripts/views/questions/index.js
deleted file mode 100644
index 2d24174..0000000
--- a/lib/assets/javascripts/views/questions/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-$(() => {
- $('.question_new_link').on('click', (e) => {
- e.preventDefault();
- $(e.target).hide();
- $(e.target).closest('.row').find('.question_new').show();
- });
-});
diff --git a/lib/assets/javascripts/views/questions/new_edit.js b/lib/assets/javascripts/views/questions/new_edit.js
deleted file mode 100644
index ecaf228..0000000
--- a/lib/assets/javascripts/views/questions/new_edit.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Tinymce } from '../../utils/tinymce';
-import ariatiseForm from '../../utils/ariatiseForm';
-import onChangeQuestionFormat from './sharedEventHandlers';
-
-$(() => {
- Tinymce.init({ selector: '.question' });
- ariatiseForm({ selector: '.question_form' });
- $('.edit_question_cancel').on('click', (e) => {
- e.preventDefault();
- const questionEdit = $(e.target).closest('.question_edit');
- questionEdit.hide();
- questionEdit.parent().find('.question_show').show();
- });
- $('.new_question_cancel').on('click', (e) => {
- const questionNew = $(e.target).closest('.question_new');
- questionNew.hide();
- questionNew.closest('.row').find('.question_new_link').show();
- });
- $('[name="question[question_format_id]"]').on('change', onChangeQuestionFormat);
-});
diff --git a/lib/assets/javascripts/views/questions/sharedEventHandlers.js b/lib/assets/javascripts/views/questions/sharedEventHandlers.js
deleted file mode 100644
index 484dece..0000000
--- a/lib/assets/javascripts/views/questions/sharedEventHandlers.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const onChangeQuestionFormat = (e) => {
- const source = e.target;
- const selected = source.value;
- const defaultValue = $(source).closest('form').find('[data-attribute="default_value"]');
- const questionOptions = $(source).closest('form').find('[data-attribute="question_options"]');
- const opComment = $(source).closest('form').find('[data-attribute="option_comment"]');
- switch (selected) {
- case '1':
- questionOptions.hide();
- opComment.hide();
- defaultValue.show();
- defaultValue.find('[data-attribute="textfield"]').hide();
- defaultValue.find('[data-attribute="textarea"]').show();
- break;
- case '2':
- questionOptions.hide();
- opComment.hide();
- defaultValue.show();
- defaultValue.find('[data-attribute="textarea"]').hide();
- defaultValue.find('[data-attribute="textfield"]').show();
- break;
- case '3':
- case '4':
- case '5':
- case '6':
- defaultValue.hide();
- questionOptions.show();
- opComment.show();
- break;
- case '7':
- defaultValue.hide();
- questionOptions.hide();
- opComment.show();
- break;
- default :
- break;
- }
-};
-
-export { onChangeQuestionFormat as default };
diff --git a/lib/assets/javascripts/views/questions/show.js b/lib/assets/javascripts/views/questions/show.js
deleted file mode 100644
index 7a744fd..0000000
--- a/lib/assets/javascripts/views/questions/show.js
+++ /dev/null
@@ -1,22 +0,0 @@
-$(() => {
- $('.question_edit_link').on('click', (e) => {
- const source = e.target;
- const target = $(source).attr('href');
- $(source).closest('.question_show').hide();
- $(target).show();
- });
-
- $('.annotations_button').on('click', (e) => {
- e.preventDefault();
- const target = $(e.target).attr('href');
- $(target).show();
- $(target).closest('.col-md-12').find('.show_annotations_div').hide();
- });
-
- $('.cancel_edit_annotations').on('click', (e) => {
- e.preventDefault();
- const target = $(e.target).attr('href');
- $(target).hide();
- $(target).closest('.col-md-12').find('.show_annotations_div').show();
- });
-});
diff --git a/lib/assets/javascripts/views/sections/edit.js b/lib/assets/javascripts/views/sections/edit.js
deleted file mode 100644
index 44a1faa..0000000
--- a/lib/assets/javascripts/views/sections/edit.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import { Tinymce } from '../../utils/tinymce';
-
-$(() => {
- Tinymce.init({ selector: '.section' });
-});
diff --git a/lib/assets/javascripts/views/sections/index.js b/lib/assets/javascripts/views/sections/index.js
deleted file mode 100644
index 6ef5ba3..0000000
--- a/lib/assets/javascripts/views/sections/index.js
+++ /dev/null
@@ -1,6 +0,0 @@
-$(() => {
- $('.section_new_link').on('click', (e) => {
- $(e.target).hide();
- $(e.target).closest('.row').find('.section_new').show();
- });
-});
diff --git a/lib/assets/javascripts/views/sections/new.js b/lib/assets/javascripts/views/sections/new.js
deleted file mode 100644
index e703eca..0000000
--- a/lib/assets/javascripts/views/sections/new.js
+++ /dev/null
@@ -1,7 +0,0 @@
-$(() => {
- $('.section_new_cancel').on('click', (e) => {
- const sectionNew = $(e.target).closest('.section_new');
- sectionNew.hide();
- sectionNew.closest('.row').find('.section_new_link').show();
- });
-});
diff --git a/lib/assets/javascripts/views/super_admin/notifications/edit.js b/lib/assets/javascripts/views/super_admin/notifications/edit.js
new file mode 100644
index 0000000..7ec8378
--- /dev/null
+++ b/lib/assets/javascripts/views/super_admin/notifications/edit.js
@@ -0,0 +1,11 @@
+import ariatiseForm from '../../../utils/ariatiseForm';
+import { Tinymce } from '../../../utils/tinymce';
+
+$(() => {
+ Tinymce.init({
+ selector: '#notification_body',
+ forced_root_block: '',
+ toolbar: 'bold italic underline | link',
+ });
+ ariatiseForm({ selector: 'form.notification' });
+});
diff --git a/lib/assets/package-lock.json b/lib/assets/package-lock.json
index 051345a..37da536 100644
--- a/lib/assets/package-lock.json
+++ b/lib/assets/package-lock.json
@@ -4,6 +4,11 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "@types/jquery": {
+ "version": "2.0.49",
+ "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-2.0.49.tgz",
+ "integrity": "sha512-/9xLnYmohN/vD2gDnLS4cym8TUmrJu7DvZa/LELKzZjdPsvWVJiedsdu2SXNtb/DA7FGimqL2g0IoyhbNKLl8g=="
+ },
"abbrev": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
@@ -21,9 +26,9 @@
}
},
"acorn": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz",
- "integrity": "sha512-vOk6uEMctu0vQrvuSqFdJyqj1Q0S5VTDL79qtjo+DhRr+1mmaD+tluFSCZqhvi/JUhXSzoZN2BhtstaPEeE8cw==",
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
+ "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==",
"dev": true
},
"acorn-dynamic-import": {
@@ -79,9 +84,9 @@
}
},
"ajv-keywords": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
- "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
+ "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
"dev": true
},
"align-text": {
@@ -108,9 +113,9 @@
"dev": true
},
"ansi-escapes": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz",
- "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+ "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==",
"dev": true
},
"ansi-regex": {
@@ -152,9 +157,9 @@
}
},
"argparse": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
- "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"requires": {
"sprintf-js": "1.0.3"
@@ -175,6 +180,12 @@
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
"dev": true
},
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
"array-find-index": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
@@ -227,14 +238,14 @@
"dev": true
},
"asn1.js": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz",
- "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=",
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
"dev": true,
"requires": {
"bn.js": "4.11.8",
"inherits": "2.0.3",
- "minimalistic-assert": "1.0.0"
+ "minimalistic-assert": "1.0.1"
}
},
"assert": {
@@ -252,10 +263,16 @@
"integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
"dev": true
},
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true
+ },
"async": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
- "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==",
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
+ "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
"dev": true,
"requires": {
"lodash": "4.17.4"
@@ -279,6 +296,12 @@
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
"dev": true
},
+ "atob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
+ "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
+ "dev": true
+ },
"autoprefixer": {
"version": "6.7.7",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
@@ -286,10 +309,10 @@
"dev": true,
"requires": {
"browserslist": "1.7.7",
- "caniuse-db": "1.0.30000717",
+ "caniuse-db": "1.0.30000832",
"normalize-range": "0.1.2",
"num2fraction": "1.2.2",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0"
}
},
@@ -317,13 +340,13 @@
}
},
"babel-core": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
- "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
+ "version": "6.26.3",
+ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
+ "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==",
"dev": true,
"requires": {
"babel-code-frame": "6.26.0",
- "babel-generator": "6.26.0",
+ "babel-generator": "6.26.1",
"babel-helpers": "6.24.1",
"babel-messages": "6.23.0",
"babel-register": "6.26.0",
@@ -332,21 +355,38 @@
"babel-traverse": "6.26.0",
"babel-types": "6.26.0",
"babylon": "6.18.0",
- "convert-source-map": "1.5.0",
- "debug": "2.6.8",
+ "convert-source-map": "1.5.1",
+ "debug": "2.6.9",
"json5": "0.5.1",
"lodash": "4.17.4",
"minimatch": "3.0.4",
"path-is-absolute": "1.0.1",
- "private": "0.1.7",
+ "private": "0.1.8",
"slash": "1.0.0",
"source-map": "0.5.7"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "private": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
+ "dev": true
+ }
}
},
"babel-generator": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz",
- "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=",
+ "version": "6.26.1",
+ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+ "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
"dev": true,
"requires": {
"babel-messages": "6.23.0",
@@ -462,9 +502,9 @@
}
},
"babel-loader": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz",
- "integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==",
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.4.tgz",
+ "integrity": "sha512-/hbyEvPzBJuGpk9o80R0ZyTej6heEOr59GoEUtn8qFKbnx4cJm9FWES6J/iv644sYgrtVw9JJQkjaLW/bqb5gw==",
"dev": true,
"requires": {
"find-cache-dir": "1.0.0",
@@ -800,13 +840,13 @@
"integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
"dev": true,
"requires": {
- "babel-core": "6.26.0",
+ "babel-core": "6.26.3",
"babel-runtime": "6.26.0",
"core-js": "2.5.0",
"home-or-tmp": "2.0.0",
"lodash": "4.17.4",
"mkdirp": "0.5.1",
- "source-map-support": "0.4.16"
+ "source-map-support": "0.4.18"
}
},
"babel-runtime": {
@@ -879,6 +919,79 @@
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "requires": {
+ "cache-base": "1.0.1",
+ "class-utils": "0.3.6",
+ "component-emitter": "1.2.1",
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "mixin-deep": "1.3.1",
+ "pascalcase": "0.1.1"
+ },
+ "dependencies": {
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "dev": true
+ },
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
"base64-arraybuffer": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
@@ -886,9 +999,9 @@
"dev": true
},
"base64-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
- "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
+ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
"dev": true
},
"base64id": {
@@ -923,9 +1036,9 @@
"dev": true
},
"binary-extensions": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz",
- "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
+ "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
"dev": true
},
"blob": {
@@ -944,9 +1057,9 @@
}
},
"bluebird": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
- "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=",
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+ "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
"dev": true
},
"bn.js": {
@@ -956,36 +1069,36 @@
"dev": true
},
"body-parser": {
- "version": "1.17.2",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz",
- "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=",
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
+ "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
"dev": true,
"requires": {
- "bytes": "2.4.0",
- "content-type": "1.0.2",
- "debug": "2.6.7",
- "depd": "1.1.1",
- "http-errors": "1.6.2",
- "iconv-lite": "0.4.15",
+ "bytes": "3.0.0",
+ "content-type": "1.0.4",
+ "debug": "2.6.9",
+ "depd": "1.1.2",
+ "http-errors": "1.6.3",
+ "iconv-lite": "0.4.19",
"on-finished": "2.3.0",
- "qs": "6.4.0",
- "raw-body": "2.2.0",
- "type-is": "1.6.15"
+ "qs": "6.5.1",
+ "raw-body": "2.3.2",
+ "type-is": "1.6.16"
},
"dependencies": {
"debug": {
- "version": "2.6.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz",
- "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=",
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dev": true,
"requires": {
"ms": "2.0.0"
}
},
- "iconv-lite": {
- "version": "0.4.15",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
- "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=",
+ "qs": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
"dev": true
}
}
@@ -1032,33 +1145,34 @@
"dev": true
},
"browserify-aes": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.6.tgz",
- "integrity": "sha1-Xncl297x/Vkw1OurSFZ85FHEigo=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"dev": true,
"requires": {
"buffer-xor": "1.0.3",
"cipher-base": "1.0.4",
- "create-hash": "1.1.3",
- "evp_bytestokey": "1.0.2",
- "inherits": "2.0.3"
+ "create-hash": "1.2.0",
+ "evp_bytestokey": "1.0.3",
+ "inherits": "2.0.3",
+ "safe-buffer": "5.1.1"
}
},
"browserify-cipher": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
- "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
"dev": true,
"requires": {
- "browserify-aes": "1.0.6",
- "browserify-des": "1.0.0",
- "evp_bytestokey": "1.0.2"
+ "browserify-aes": "1.2.0",
+ "browserify-des": "1.0.1",
+ "evp_bytestokey": "1.0.3"
}
},
"browserify-des": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
- "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz",
+ "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==",
"dev": true,
"requires": {
"cipher-base": "1.0.4",
@@ -1073,7 +1187,7 @@
"dev": true,
"requires": {
"bn.js": "4.11.8",
- "randombytes": "2.0.5"
+ "randombytes": "2.0.6"
}
},
"browserify-sign": {
@@ -1084,20 +1198,20 @@
"requires": {
"bn.js": "4.11.8",
"browserify-rsa": "4.0.1",
- "create-hash": "1.1.3",
- "create-hmac": "1.1.6",
+ "create-hash": "1.2.0",
+ "create-hmac": "1.1.7",
"elliptic": "6.4.0",
"inherits": "2.0.3",
- "parse-asn1": "5.1.0"
+ "parse-asn1": "5.1.1"
}
},
"browserify-zlib": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
- "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
"dev": true,
"requires": {
- "pako": "0.2.9"
+ "pako": "1.0.6"
}
},
"browserslist": {
@@ -1106,8 +1220,8 @@
"integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
"dev": true,
"requires": {
- "caniuse-db": "1.0.30000717",
- "electron-to-chromium": "1.3.18"
+ "caniuse-db": "1.0.30000832",
+ "electron-to-chromium": "1.3.44"
}
},
"buffer": {
@@ -1116,11 +1230,17 @@
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
"dev": true,
"requires": {
- "base64-js": "1.2.1",
- "ieee754": "1.1.8",
+ "base64-js": "1.3.0",
+ "ieee754": "1.1.11",
"isarray": "1.0.0"
}
},
+ "buffer-from": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
+ "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==",
+ "dev": true
+ },
"buffer-xor": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
@@ -1140,11 +1260,94 @@
"dev": true
},
"bytes": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz",
- "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
"dev": true
},
+ "cacache": {
+ "version": "10.0.4",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
+ "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==",
+ "dev": true,
+ "requires": {
+ "bluebird": "3.5.1",
+ "chownr": "1.0.1",
+ "glob": "7.1.2",
+ "graceful-fs": "4.1.11",
+ "lru-cache": "4.1.1",
+ "mississippi": "2.0.0",
+ "mkdirp": "0.5.1",
+ "move-concurrently": "1.0.1",
+ "promise-inflight": "1.0.1",
+ "rimraf": "2.6.2",
+ "ssri": "5.3.0",
+ "unique-filename": "1.1.0",
+ "y18n": "4.0.0"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "dev": true,
+ "requires": {
+ "glob": "7.1.2"
+ }
+ },
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
+ }
+ }
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "1.0.0",
+ "component-emitter": "1.2.1",
+ "get-value": "2.0.6",
+ "has-value": "1.0.0",
+ "isobject": "3.0.1",
+ "set-value": "2.0.0",
+ "to-object-path": "0.3.0",
+ "union-value": "1.0.0",
+ "unset-value": "1.0.0"
+ },
+ "dependencies": {
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
"caller-path": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
@@ -1189,15 +1392,15 @@
"dev": true,
"requires": {
"browserslist": "1.7.7",
- "caniuse-db": "1.0.30000717",
+ "caniuse-db": "1.0.30000832",
"lodash.memoize": "4.1.2",
"lodash.uniq": "4.5.0"
}
},
"caniuse-db": {
- "version": "1.0.30000717",
- "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000717.tgz",
- "integrity": "sha1-J931/szdM4yZpiyXiMJpT5n2ftc=",
+ "version": "1.0.30000832",
+ "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000832.tgz",
+ "integrity": "sha1-r+NMn3xiE5/RxgfbKrcwi7tqUVg=",
"dev": true
},
"caseless": {
@@ -1214,14 +1417,6 @@
"requires": {
"align-text": "0.1.4",
"lazy-cache": "1.0.4"
- },
- "dependencies": {
- "lazy-cache": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
- "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
- "dev": true
- }
}
},
"chalk": {
@@ -1237,6 +1432,45 @@
"supports-color": "2.0.0"
}
},
+ "chardet": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
+ "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
+ "dev": true
+ },
+ "chart.js": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.7.2.tgz",
+ "integrity": "sha512-90wl3V9xRZ8tnMvMlpcW+0Yg13BelsGS9P9t0ClaDxv/hdypHDr/YAGf+728m11P5ljwyB0ZHfPKCapZFqSqYA==",
+ "requires": {
+ "chartjs-color": "2.2.0",
+ "moment": "2.22.1"
+ }
+ },
+ "chartjs-color": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.2.0.tgz",
+ "integrity": "sha1-hKL7dVeH7YXDndbdjHsdiEKbrq4=",
+ "requires": {
+ "chartjs-color-string": "0.5.0",
+ "color-convert": "0.5.3"
+ },
+ "dependencies": {
+ "color-convert": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
+ "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0="
+ }
+ }
+ },
+ "chartjs-color-string": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.5.0.tgz",
+ "integrity": "sha512-amWNvCOXlOUYxZVDSa0YOab5K/lmEhbFNKI55PWc4mlv28BDzA7zaoQTGxSBgJMHIW+hGX8YUrvw/FH4LyhwSQ==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
"chokidar": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
@@ -1271,6 +1505,12 @@
}
}
},
+ "chownr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
+ "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
+ "dev": true
+ },
"cipher-base": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
@@ -1288,14 +1528,43 @@
"dev": true
},
"clap": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.0.tgz",
- "integrity": "sha1-WckP4+E3EEdG/xlGmiemNP9oyFc=",
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz",
+ "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==",
"dev": true,
"requires": {
"chalk": "1.1.3"
}
},
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "3.1.0",
+ "define-property": "0.2.5",
+ "isobject": "3.0.1",
+ "static-extend": "0.1.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
"cli-cursor": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
@@ -1345,21 +1614,38 @@
}
},
"clone": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz",
- "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
"dev": true
},
"clone-deep": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.3.0.tgz",
- "integrity": "sha1-NIxhrpzb4O3+BT2R/0zFIdeQ7eg=",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz",
+ "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==",
"dev": true,
"requires": {
"for-own": "1.0.0",
"is-plain-object": "2.0.4",
- "kind-of": "3.2.2",
- "shallow-clone": "0.1.2"
+ "kind-of": "6.0.2",
+ "shallow-clone": "1.0.0"
+ },
+ "dependencies": {
+ "for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+ "dev": true,
+ "requires": {
+ "for-in": "1.0.2"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
}
},
"co": {
@@ -1374,7 +1660,7 @@
"integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=",
"dev": true,
"requires": {
- "q": "1.5.0"
+ "q": "1.5.1"
}
},
"code-point-at": {
@@ -1383,21 +1669,31 @@
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
},
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "requires": {
+ "map-visit": "1.0.0",
+ "object-visit": "1.0.1"
+ }
+ },
"color": {
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz",
"integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=",
"dev": true,
"requires": {
- "clone": "1.0.2",
- "color-convert": "1.9.0",
+ "clone": "1.0.4",
+ "color-convert": "1.9.1",
"color-string": "0.3.0"
}
},
"color-convert": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
- "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+ "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
"dev": true,
"requires": {
"color-name": "1.1.3"
@@ -1406,8 +1702,7 @@
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
- "dev": true
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"color-string": {
"version": "0.3.0",
@@ -1453,6 +1748,12 @@
"delayed-stream": "1.0.0"
}
},
+ "commander": {
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+ "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+ "dev": true
+ },
"commondir": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
@@ -1484,26 +1785,38 @@
"dev": true
},
"concat-stream": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
- "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
"dev": true,
"requires": {
+ "buffer-from": "1.0.0",
"inherits": "2.0.3",
"readable-stream": "2.3.3",
"typedarray": "0.0.6"
}
},
"connect": {
- "version": "3.6.3",
- "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.3.tgz",
- "integrity": "sha512-GLSZqgjVxPvGYVD/2vz//gS201MEXk4b7t3nHV6OVnTdDNWi/Gm7Rpxs/ybvljPWvULys/wrzIV3jB3YvEc3nQ==",
+ "version": "3.6.6",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
+ "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
"dev": true,
"requires": {
- "debug": "2.6.8",
- "finalhandler": "1.0.4",
- "parseurl": "1.3.1",
- "utils-merge": "1.0.0"
+ "debug": "2.6.9",
+ "finalhandler": "1.1.0",
+ "parseurl": "1.3.2",
+ "utils-merge": "1.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
}
},
"console-browserify": {
@@ -1534,15 +1847,15 @@
"dev": true
},
"content-type": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz",
- "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
"dev": true
},
"convert-source-map": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz",
- "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=",
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
+ "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
"dev": true
},
"cookie": {
@@ -1551,34 +1864,40 @@
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
"dev": true
},
- "copy-webpack-plugin": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.0.1.tgz",
- "integrity": "sha1-lyjjg7lDFgUNDHRjlY8rhcCqggA=",
+ "copy-concurrently": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+ "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
"dev": true,
"requires": {
- "bluebird": "2.11.0",
- "fs-extra": "0.26.7",
- "glob": "6.0.4",
- "is-glob": "3.1.0",
- "loader-utils": "0.2.17",
- "lodash": "4.17.4",
+ "aproba": "1.1.2",
+ "fs-write-stream-atomic": "1.0.10",
+ "iferr": "0.1.5",
+ "mkdirp": "0.5.1",
+ "rimraf": "2.6.1",
+ "run-queue": "1.0.3"
+ }
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true
+ },
+ "copy-webpack-plugin": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.5.1.tgz",
+ "integrity": "sha512-OlTo6DYg0XfTKOF8eLf79wcHm4Ut10xU2cRBRPMW/NA5F9VMjZGTfRHWDIYC3s+1kObGYrBLshXWU1K0hILkNQ==",
+ "dev": true,
+ "requires": {
+ "cacache": "10.0.4",
+ "find-cache-dir": "1.0.0",
+ "globby": "7.1.1",
+ "is-glob": "4.0.0",
+ "loader-utils": "1.1.0",
"minimatch": "3.0.4",
- "node-dir": "0.1.17"
- },
- "dependencies": {
- "loader-utils": {
- "version": "0.2.17",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
- "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
- "dev": true,
- "requires": {
- "big.js": "3.1.3",
- "emojis-list": "2.1.0",
- "json5": "0.5.1",
- "object-assign": "4.1.1"
- }
- }
+ "p-limit": "1.2.0",
+ "serialize-javascript": "1.5.0"
}
},
"core-js": {
@@ -1594,9 +1913,9 @@
"dev": true
},
"create-ecdh": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
- "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.1.tgz",
+ "integrity": "sha512-iZvCCg8XqHQZ1ioNBTzXS/cQSkqkqcPs8xSX4upNB+DAk9Ht3uzQf2J32uAHNCne8LDmKr29AgZrEs4oIrwLuQ==",
"dev": true,
"requires": {
"bn.js": "4.11.8",
@@ -1604,29 +1923,30 @@
}
},
"create-hash": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
- "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"dev": true,
"requires": {
"cipher-base": "1.0.4",
"inherits": "2.0.3",
- "ripemd160": "2.0.1",
- "sha.js": "2.4.8"
+ "md5.js": "1.3.4",
+ "ripemd160": "2.0.2",
+ "sha.js": "2.4.11"
}
},
"create-hmac": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
- "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"dev": true,
"requires": {
"cipher-base": "1.0.4",
- "create-hash": "1.1.3",
+ "create-hash": "1.2.0",
"inherits": "2.0.3",
- "ripemd160": "2.0.1",
+ "ripemd160": "2.0.2",
"safe-buffer": "5.1.1",
- "sha.js": "2.4.8"
+ "sha.js": "2.4.11"
}
},
"cross-spawn": {
@@ -1650,21 +1970,22 @@
}
},
"crypto-browserify": {
- "version": "3.11.1",
- "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz",
- "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==",
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
"dev": true,
"requires": {
- "browserify-cipher": "1.0.0",
+ "browserify-cipher": "1.0.1",
"browserify-sign": "4.0.4",
- "create-ecdh": "4.0.0",
- "create-hash": "1.1.3",
- "create-hmac": "1.1.6",
- "diffie-hellman": "5.0.2",
+ "create-ecdh": "4.0.1",
+ "create-hash": "1.2.0",
+ "create-hmac": "1.1.7",
+ "diffie-hellman": "5.0.3",
"inherits": "2.0.3",
- "pbkdf2": "3.0.13",
- "public-encrypt": "4.0.0",
- "randombytes": "2.0.5"
+ "pbkdf2": "3.0.16",
+ "public-encrypt": "4.0.2",
+ "randombytes": "2.0.6",
+ "randomfill": "1.0.4"
}
},
"css-color-names": {
@@ -1674,9 +1995,9 @@
"dev": true
},
"css-loader": {
- "version": "0.28.5",
- "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.5.tgz",
- "integrity": "sha512-/FJmsDD8e6xZOBHMFShN/BCjnrEybq0spYaTZ1QoZ10/jhUa1LDDojQELu/JJ1ykZZjt0nSwkYrb2Mfx3bZx3Q==",
+ "version": "0.28.11",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz",
+ "integrity": "sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg==",
"dev": true,
"requires": {
"babel-code-frame": "6.26.0",
@@ -1686,8 +2007,8 @@
"loader-utils": "1.1.0",
"lodash.camelcase": "4.3.0",
"object-assign": "4.1.1",
- "postcss": "5.2.17",
- "postcss-modules-extract-imports": "1.1.0",
+ "postcss": "5.2.18",
+ "postcss-modules-extract-imports": "1.2.0",
"postcss-modules-local-by-default": "1.2.0",
"postcss-modules-scope": "1.1.0",
"postcss-modules-values": "1.3.0",
@@ -1736,7 +2057,7 @@
"defined": "1.0.0",
"has": "1.0.1",
"object-assign": "4.1.1",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-calc": "5.3.1",
"postcss-colormin": "2.2.2",
"postcss-convert-values": "2.6.1",
@@ -1771,7 +2092,7 @@
"integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=",
"dev": true,
"requires": {
- "clap": "1.2.0",
+ "clap": "1.2.3",
"source-map": "0.5.7"
}
},
@@ -1790,13 +2111,19 @@
"integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
"dev": true
},
+ "cyclist": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
+ "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=",
+ "dev": true
+ },
"d": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
"integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
"dev": true,
"requires": {
- "es5-ext": "0.10.29"
+ "es5-ext": "0.10.42"
}
},
"dashdash": {
@@ -1837,12 +2164,71 @@
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
"dev": true
},
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "dev": true
+ },
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true
},
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2",
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
"defined": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
@@ -1857,11 +2243,41 @@
"requires": {
"globby": "5.0.0",
"is-path-cwd": "1.0.0",
- "is-path-in-cwd": "1.0.0",
+ "is-path-in-cwd": "1.0.1",
"object-assign": "4.1.1",
"pify": "2.3.0",
"pinkie-promise": "2.0.1",
"rimraf": "2.6.1"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.3",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "globby": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+ "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+ "dev": true,
+ "requires": {
+ "array-union": "1.0.2",
+ "arrify": "1.0.1",
+ "glob": "7.1.2",
+ "object-assign": "4.1.1",
+ "pify": "2.3.0",
+ "pinkie-promise": "2.0.1"
+ }
+ }
}
},
"delayed-stream": {
@@ -1877,9 +2293,9 @@
"dev": true
},
"depd": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
- "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
"dev": true
},
"des.js": {
@@ -1889,7 +2305,7 @@
"dev": true,
"requires": {
"inherits": "2.0.3",
- "minimalistic-assert": "1.0.0"
+ "minimalistic-assert": "1.0.1"
}
},
"detect-indent": {
@@ -1908,24 +2324,33 @@
"dev": true
},
"diffie-hellman": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
- "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"dev": true,
"requires": {
"bn.js": "4.11.8",
- "miller-rabin": "4.0.0",
- "randombytes": "2.0.5"
+ "miller-rabin": "4.0.1",
+ "randombytes": "2.0.6"
+ }
+ },
+ "dir-glob": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz",
+ "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==",
+ "dev": true,
+ "requires": {
+ "arrify": "1.0.1",
+ "path-type": "3.0.0"
}
},
"doctrine": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz",
- "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
"dev": true,
"requires": {
- "esutils": "2.0.2",
- "isarray": "1.0.0"
+ "esutils": "2.0.2"
}
},
"dom-serialize": {
@@ -1941,11 +2366,23 @@
}
},
"domain-browser": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
- "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
"dev": true
},
+ "duplexify": {
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz",
+ "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "1.4.1",
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3",
+ "stream-shift": "1.0.0"
+ }
+ },
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
@@ -1963,9 +2400,9 @@
"dev": true
},
"electron-to-chromium": {
- "version": "1.3.18",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.18.tgz",
- "integrity": "sha1-PcyZ2j5rZl9qu8ccKK1Ros1zGpw=",
+ "version": "1.3.44",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.44.tgz",
+ "integrity": "sha1-72sVCmDVIwgjiMra2ICF7NL9RoQ=",
"dev": true
},
"elliptic": {
@@ -1979,7 +2416,7 @@
"hash.js": "1.1.3",
"hmac-drbg": "1.0.1",
"inherits": "2.0.3",
- "minimalistic-assert": "1.0.0",
+ "minimalistic-assert": "1.0.1",
"minimalistic-crypto-utils": "1.0.1"
}
},
@@ -1990,11 +2427,20 @@
"dev": true
},
"encodeurl": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
- "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
"dev": true
},
+ "end-of-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+ "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "dev": true,
+ "requires": {
+ "once": "1.4.0"
+ }
+ },
"engine.io": {
"version": "1.8.3",
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz",
@@ -2102,12 +2548,12 @@
"dev": true
},
"errno": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz",
- "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=",
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+ "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
"dev": true,
"requires": {
- "prr": "0.0.0"
+ "prr": "1.0.1"
}
},
"error-ex": {
@@ -2120,23 +2566,24 @@
}
},
"es5-ext": {
- "version": "0.10.29",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.29.tgz",
- "integrity": "sha512-KXla9NXo5sdaEkGSmbFPYgjH6m75kxsthL6GDRSug/Y2OiMoYm0I9giL39j4cgmaFmAbkIFJ6gG+SGKnLSmOvA==",
+ "version": "0.10.42",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.42.tgz",
+ "integrity": "sha512-AJxO1rmPe1bDEfSR6TJ/FgMFYuTBhR5R57KW58iCkYACMyFbrkqVyzXSurYoScDGvgyMpk7uRF/lPUPPTmsRSA==",
"dev": true,
"requires": {
- "es6-iterator": "2.0.1",
- "es6-symbol": "3.1.1"
+ "es6-iterator": "2.0.3",
+ "es6-symbol": "3.1.1",
+ "next-tick": "1.0.0"
}
},
"es6-iterator": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
- "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
"dev": true,
"requires": {
"d": "1.0.0",
- "es5-ext": "0.10.29",
+ "es5-ext": "0.10.42",
"es6-symbol": "3.1.1"
}
},
@@ -2147,8 +2594,8 @@
"dev": true,
"requires": {
"d": "1.0.0",
- "es5-ext": "0.10.29",
- "es6-iterator": "2.0.1",
+ "es5-ext": "0.10.42",
+ "es6-iterator": "2.0.3",
"es6-set": "0.1.5",
"es6-symbol": "3.1.1",
"event-emitter": "0.3.5"
@@ -2161,8 +2608,8 @@
"dev": true,
"requires": {
"d": "1.0.0",
- "es5-ext": "0.10.29",
- "es6-iterator": "2.0.1",
+ "es5-ext": "0.10.42",
+ "es6-iterator": "2.0.3",
"es6-symbol": "3.1.1",
"event-emitter": "0.3.5"
}
@@ -2174,7 +2621,7 @@
"dev": true,
"requires": {
"d": "1.0.0",
- "es5-ext": "0.10.29"
+ "es5-ext": "0.10.42"
}
},
"es6-weak-map": {
@@ -2184,8 +2631,8 @@
"dev": true,
"requires": {
"d": "1.0.0",
- "es5-ext": "0.10.29",
- "es6-iterator": "2.0.1",
+ "es5-ext": "0.10.42",
+ "es6-iterator": "2.0.3",
"es6-symbol": "3.1.1"
}
},
@@ -2209,38 +2656,38 @@
"requires": {
"es6-map": "0.1.5",
"es6-weak-map": "2.0.2",
- "esrecurse": "4.2.0",
+ "esrecurse": "4.2.1",
"estraverse": "4.2.0"
}
},
"eslint": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.5.0.tgz",
- "integrity": "sha1-u3XTuL3pf7XhPvzVOXRGd/6wGcM=",
+ "version": "4.19.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
+ "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
"dev": true,
"requires": {
- "ajv": "5.2.2",
+ "ajv": "5.5.2",
"babel-code-frame": "6.26.0",
- "chalk": "2.1.0",
- "concat-stream": "1.6.0",
+ "chalk": "2.4.1",
+ "concat-stream": "1.6.2",
"cross-spawn": "5.1.0",
- "debug": "2.6.8",
- "doctrine": "2.0.0",
+ "debug": "3.1.0",
+ "doctrine": "2.1.0",
"eslint-scope": "3.7.1",
- "espree": "3.5.0",
- "esquery": "1.0.0",
- "estraverse": "4.2.0",
+ "eslint-visitor-keys": "1.0.0",
+ "espree": "3.5.4",
+ "esquery": "1.0.1",
"esutils": "2.0.2",
"file-entry-cache": "2.0.0",
"functional-red-black-tree": "1.0.1",
"glob": "7.1.2",
- "globals": "9.18.0",
- "ignore": "3.3.3",
+ "globals": "11.5.0",
+ "ignore": "3.3.8",
"imurmurhash": "0.1.4",
- "inquirer": "3.2.2",
- "is-resolvable": "1.0.0",
- "js-yaml": "3.9.1",
- "json-stable-stringify": "1.0.1",
+ "inquirer": "3.3.0",
+ "is-resolvable": "1.1.0",
+ "js-yaml": "3.11.0",
+ "json-stable-stringify-without-jsonify": "1.0.1",
"levn": "0.3.0",
"lodash": "4.17.4",
"minimatch": "3.0.4",
@@ -2248,16 +2695,29 @@
"natural-compare": "1.4.0",
"optionator": "0.8.2",
"path-is-inside": "1.0.2",
- "pluralize": "4.0.0",
+ "pluralize": "7.0.0",
"progress": "2.0.0",
+ "regexpp": "1.1.0",
"require-uncached": "1.0.3",
"semver": "5.4.1",
"strip-ansi": "4.0.0",
"strip-json-comments": "2.0.1",
- "table": "4.0.1",
+ "table": "4.0.2",
"text-table": "0.2.0"
},
"dependencies": {
+ "ajv": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+ "dev": true,
+ "requires": {
+ "co": "4.6.0",
+ "fast-deep-equal": "1.0.0",
+ "fast-json-stable-stringify": "2.0.0",
+ "json-schema-traverse": "0.3.1"
+ }
+ },
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
@@ -2265,23 +2725,32 @@
"dev": true
},
"ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
- "color-convert": "1.9.0"
+ "color-convert": "1.9.1"
}
},
"chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"dev": true,
"requires": {
- "ansi-styles": "3.2.0",
+ "ansi-styles": "3.2.1",
"escape-string-regexp": "1.0.5",
- "supports-color": "4.2.1"
+ "supports-color": "5.4.0"
+ }
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
}
},
"esprima": {
@@ -2304,19 +2773,25 @@
"path-is-absolute": "1.0.1"
}
},
+ "globals": {
+ "version": "11.5.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz",
+ "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==",
+ "dev": true
+ },
"has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"js-yaml": {
- "version": "3.9.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz",
- "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==",
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz",
+ "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
"dev": true,
"requires": {
- "argparse": "1.0.9",
+ "argparse": "1.0.10",
"esprima": "4.0.0"
}
},
@@ -2330,33 +2805,44 @@
}
},
"supports-color": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz",
- "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==",
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
"dev": true,
"requires": {
- "has-flag": "2.0.0"
+ "has-flag": "3.0.0"
}
}
}
},
"eslint-config-airbnb-base": {
- "version": "11.3.1",
- "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.3.1.tgz",
- "integrity": "sha512-BXVH7PV5yiLjnkv49iOLJ8dWp+ljZf310ytQpqwrunFADiEbWRyN0tPGDU36FgEbdLvhJDWcJOngYDzPF4shDw==",
+ "version": "11.3.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.3.2.tgz",
+ "integrity": "sha512-/fhjt/VqzBA2SRsx7ErDtv6Ayf+XLw9LIOqmpBuHFCVwyJo2EtzGWMB9fYRFBoWWQLxmNmCpenNiH0RxyeS41w==",
"dev": true,
"requires": {
"eslint-restricted-globals": "0.1.1"
}
},
"eslint-import-resolver-node": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz",
- "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==",
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz",
+ "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==",
"dev": true,
"requires": {
- "debug": "2.6.8",
- "resolve": "1.4.0"
+ "debug": "2.6.9",
+ "resolve": "1.7.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
}
},
"eslint-loader": {
@@ -2373,9 +2859,9 @@
}
},
"eslint-module-utils": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz",
- "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz",
+ "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=",
"dev": true,
"requires": {
"debug": "2.6.8",
@@ -2413,21 +2899,21 @@
}
},
"eslint-plugin-import": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz",
- "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==",
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.11.0.tgz",
+ "integrity": "sha1-Fa7qN6Z0mdhI6OmBgG1GJ7VQOBY=",
"dev": true,
"requires": {
- "builtin-modules": "1.1.1",
"contains-path": "0.1.0",
"debug": "2.6.8",
"doctrine": "1.5.0",
- "eslint-import-resolver-node": "0.3.1",
- "eslint-module-utils": "2.1.1",
+ "eslint-import-resolver-node": "0.3.2",
+ "eslint-module-utils": "2.2.0",
"has": "1.0.1",
- "lodash.cond": "4.5.2",
+ "lodash": "4.17.4",
"minimatch": "3.0.4",
- "read-pkg-up": "2.0.0"
+ "read-pkg-up": "2.0.0",
+ "resolve": "1.7.1"
},
"dependencies": {
"doctrine": {
@@ -2454,17 +2940,23 @@
"integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
"dev": true,
"requires": {
- "esrecurse": "4.2.0",
+ "esrecurse": "4.2.1",
"estraverse": "4.2.0"
}
},
+ "eslint-visitor-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+ "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+ "dev": true
+ },
"espree": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.0.tgz",
- "integrity": "sha1-mDWGJb3QVYYeon4oZ+pyn69GPY0=",
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
"dev": true,
"requires": {
- "acorn": "5.1.1",
+ "acorn": "5.5.3",
"acorn-jsx": "3.0.1"
}
},
@@ -2475,22 +2967,21 @@
"dev": true
},
"esquery": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
- "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+ "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
"dev": true,
"requires": {
"estraverse": "4.2.0"
}
},
"esrecurse": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
- "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
"dev": true,
"requires": {
- "estraverse": "4.2.0",
- "object-assign": "4.1.1"
+ "estraverse": "4.2.0"
}
},
"estraverse": {
@@ -2512,13 +3003,13 @@
"dev": true,
"requires": {
"d": "1.0.0",
- "es5-ext": "0.10.29"
+ "es5-ext": "0.10.42"
}
},
"eventemitter3": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
- "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
+ "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==",
"dev": true
},
"events": {
@@ -2528,9 +3019,9 @@
"dev": true
},
"evp_bytestokey": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.2.tgz",
- "integrity": "sha512-ni0r0lrm7AOzsh2qC5mi9sj8S0gmj5fLNjfFpxN05FB4tAVZEKotbkjOtLPqTCX/CXT7NsUr6juZb4IFJeNNdA==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
"dev": true,
"requires": {
"md5.js": "1.3.4",
@@ -2620,15 +3111,47 @@
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
"dev": true
},
- "external-editor": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz",
- "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=",
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
"dev": true,
"requires": {
- "iconv-lite": "0.4.18",
- "jschardet": "1.5.1",
- "tmp": "0.0.31"
+ "assign-symbols": "1.0.0",
+ "is-extendable": "1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
+ "external-editor": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+ "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
+ "dev": true,
+ "requires": {
+ "chardet": "0.4.2",
+ "iconv-lite": "0.4.19",
+ "tmp": "0.0.33"
+ },
+ "dependencies": {
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "1.0.2"
+ }
+ }
}
},
"extglob": {
@@ -2649,15 +3172,15 @@
}
},
"extract-text-webpack-plugin": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.0.tgz",
- "integrity": "sha1-kMqnkHvESfM1AF46x1MrQbAN5hI=",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz",
+ "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==",
"dev": true,
"requires": {
- "async": "2.5.0",
+ "async": "2.6.0",
"loader-utils": "1.1.0",
"schema-utils": "0.3.0",
- "webpack-sources": "1.0.1"
+ "webpack-sources": "1.1.0"
}
},
"extsprintf": {
@@ -2672,6 +3195,12 @@
"integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
"dev": true
},
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
+ "dev": true
+ },
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
@@ -2699,7 +3228,7 @@
"integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
"dev": true,
"requires": {
- "flat-cache": "1.2.2",
+ "flat-cache": "1.3.0",
"object-assign": "4.1.1"
}
},
@@ -2729,32 +3258,38 @@
"randomatic": "1.1.7",
"repeat-element": "1.1.2",
"repeat-string": "1.6.1"
- },
- "dependencies": {
- "isobject": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
- "dev": true,
- "requires": {
- "isarray": "1.0.0"
- }
- }
}
},
"finalhandler": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.4.tgz",
- "integrity": "sha512-16l/r8RgzlXKmFOhZpHBztvye+lAhC5SU7hXavnerC9UfZqZxxXl3BzL8MhffPT3kF61lj9Oav2LKEzh0ei7tg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+ "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
"dev": true,
"requires": {
- "debug": "2.6.8",
- "encodeurl": "1.0.1",
+ "debug": "2.6.9",
+ "encodeurl": "1.0.2",
"escape-html": "1.0.3",
"on-finished": "2.3.0",
- "parseurl": "1.3.1",
+ "parseurl": "1.3.2",
"statuses": "1.3.1",
"unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+ "dev": true
+ }
}
},
"find-cache-dir": {
@@ -2764,7 +3299,7 @@
"dev": true,
"requires": {
"commondir": "1.0.1",
- "make-dir": "1.0.0",
+ "make-dir": "1.2.0",
"pkg-dir": "2.0.0"
}
},
@@ -2778,9 +3313,9 @@
}
},
"flat-cache": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz",
- "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
+ "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
"dev": true,
"requires": {
"circular-json": "0.3.3",
@@ -2795,6 +3330,36 @@
"integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
"dev": true
},
+ "flush-write-stream": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
+ "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz",
+ "integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==",
+ "dev": true,
+ "requires": {
+ "debug": "3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
"font-awesome": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
@@ -2807,9 +3372,9 @@
"dev": true
},
"for-own": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
- "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
"dev": true,
"requires": {
"for-in": "1.0.2"
@@ -2832,6 +3397,25 @@
"mime-types": "2.1.16"
}
},
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "requires": {
+ "map-cache": "0.2.2"
+ }
+ },
+ "from2": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+ "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3"
+ }
+ },
"fs-access": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz",
@@ -2841,17 +3425,16 @@
"null-check": "1.0.0"
}
},
- "fs-extra": {
- "version": "0.26.7",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz",
- "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=",
+ "fs-write-stream-atomic": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+ "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
"dev": true,
"requires": {
"graceful-fs": "4.1.11",
- "jsonfile": "2.4.0",
- "klaw": "1.3.1",
- "path-is-absolute": "1.0.1",
- "rimraf": "2.6.1"
+ "iferr": "0.1.5",
+ "imurmurhash": "0.1.4",
+ "readable-stream": "2.3.3"
}
},
"fs.realpath": {
@@ -3772,9 +4355,9 @@
}
},
"function-bind": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz",
- "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
},
"functional-red-black-tree": {
@@ -3830,6 +4413,21 @@
"globule": "1.2.0"
}
},
+ "generate-function": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
+ "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=",
+ "dev": true
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
+ "dev": true,
+ "requires": {
+ "is-property": "1.0.2"
+ }
+ },
"get-caller-file": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
@@ -3848,6 +4446,12 @@
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
"dev": true
},
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true
+ },
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@@ -3938,17 +4542,17 @@
"dev": true
},
"globby": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
- "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz",
+ "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
"dev": true,
"requires": {
"array-union": "1.0.2",
- "arrify": "1.0.1",
+ "dir-glob": "2.0.0",
"glob": "7.1.2",
- "object-assign": "4.1.1",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1"
+ "ignore": "3.3.8",
+ "pify": "3.0.0",
+ "slash": "1.0.0"
},
"dependencies": {
"glob": {
@@ -3964,6 +4568,12 @@
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
}
}
},
@@ -4034,7 +4644,7 @@
"integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
"dev": true,
"requires": {
- "function-bind": "1.1.0"
+ "function-bind": "1.1.1"
}
},
"has-ansi": {
@@ -4081,13 +4691,74 @@
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
"dev": true
},
- "hash-base": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
- "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
"dev": true,
"requires": {
- "inherits": "2.0.3"
+ "get-value": "2.0.6",
+ "has-values": "1.0.0",
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "requires": {
+ "is-number": "3.0.0",
+ "kind-of": "4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "hash-base": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3",
+ "safe-buffer": "5.1.1"
}
},
"hash.js": {
@@ -4097,7 +4768,7 @@
"dev": true,
"requires": {
"inherits": "2.0.3",
- "minimalistic-assert": "1.0.0"
+ "minimalistic-assert": "1.0.1"
}
},
"hawk": {
@@ -4119,7 +4790,7 @@
"dev": true,
"requires": {
"hash.js": "1.1.3",
- "minimalistic-assert": "1.0.0",
+ "minimalistic-assert": "1.0.1",
"minimalistic-crypto-utils": "1.0.1"
}
},
@@ -4152,24 +4823,25 @@
"dev": true
},
"http-errors": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
- "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"dev": true,
"requires": {
- "depd": "1.1.1",
+ "depd": "1.1.2",
"inherits": "2.0.3",
- "setprototypeof": "1.0.3",
- "statuses": "1.3.1"
+ "setprototypeof": "1.1.0",
+ "statuses": "1.5.0"
}
},
"http-proxy": {
- "version": "1.16.2",
- "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz",
- "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=",
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
+ "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
"dev": true,
"requires": {
- "eventemitter3": "1.2.0",
+ "eventemitter3": "3.1.0",
+ "follow-redirects": "1.4.1",
"requires-port": "1.0.0"
}
},
@@ -4185,15 +4857,15 @@
}
},
"https-browserify": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz",
- "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
"dev": true
},
"iconv-lite": {
- "version": "0.4.18",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz",
- "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==",
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
"dev": true
},
"icss-replace-symbols": {
@@ -4208,67 +4880,79 @@
"integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=",
"dev": true,
"requires": {
- "postcss": "6.0.9"
+ "postcss": "6.0.22"
},
"dependencies": {
"ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
- "color-convert": "1.9.0"
+ "color-convert": "1.9.1"
}
},
"chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"dev": true,
"requires": {
- "ansi-styles": "3.2.0",
+ "ansi-styles": "3.2.1",
"escape-string-regexp": "1.0.5",
- "supports-color": "4.2.1"
+ "supports-color": "5.4.0"
}
},
"has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"postcss": {
- "version": "6.0.9",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.9.tgz",
- "integrity": "sha512-bBE2AHNEBhF23TfET6AA/lFP8ah+qHOZoFJEflFG+HgvVLdTmMOrocx/4LVVDIn3w6jUssw1q2Exk1cc9UOI8w==",
+ "version": "6.0.22",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz",
+ "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==",
"dev": true,
"requires": {
- "chalk": "2.1.0",
- "source-map": "0.5.7",
- "supports-color": "4.2.1"
+ "chalk": "2.4.1",
+ "source-map": "0.6.1",
+ "supports-color": "5.4.0"
}
},
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
"supports-color": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz",
- "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==",
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
"dev": true,
"requires": {
- "has-flag": "2.0.0"
+ "has-flag": "3.0.0"
}
}
}
},
"ieee754": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
- "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=",
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz",
+ "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==",
+ "dev": true
+ },
+ "iferr": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
"dev": true
},
"ignore": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz",
- "integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0=",
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz",
+ "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==",
"dev": true
},
"imurmurhash": {
@@ -4321,16 +5005,16 @@
"dev": true
},
"inquirer": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.2.2.tgz",
- "integrity": "sha512-bTKLzEHJVATimZO/YFdLrom0lRx1BHfRYskFHfIMVkGdp8+dIZaxuU+4yrsS1lcu6YWywVQVVsfvdwESzbeqHw==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
+ "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
"dev": true,
"requires": {
- "ansi-escapes": "2.0.0",
- "chalk": "2.1.0",
+ "ansi-escapes": "3.1.0",
+ "chalk": "2.4.1",
"cli-cursor": "2.1.0",
"cli-width": "2.2.0",
- "external-editor": "2.0.4",
+ "external-editor": "2.2.0",
"figures": "2.0.0",
"lodash": "4.17.4",
"mute-stream": "0.0.7",
@@ -4349,29 +5033,29 @@
"dev": true
},
"ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
- "color-convert": "1.9.0"
+ "color-convert": "1.9.1"
}
},
"chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"dev": true,
"requires": {
- "ansi-styles": "3.2.0",
+ "ansi-styles": "3.2.1",
"escape-string-regexp": "1.0.5",
- "supports-color": "4.2.1"
+ "supports-color": "5.4.0"
}
},
"has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"strip-ansi": {
@@ -4384,20 +5068,20 @@
}
},
"supports-color": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz",
- "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==",
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
"dev": true,
"requires": {
- "has-flag": "2.0.0"
+ "has-flag": "3.0.0"
}
}
}
},
"interpret": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz",
- "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
+ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
"dev": true
},
"invariant": {
@@ -4421,6 +5105,15 @@
"integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
"dev": true
},
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
"is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@@ -4433,13 +5126,13 @@
"integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
"dev": true,
"requires": {
- "binary-extensions": "1.10.0"
+ "binary-extensions": "1.11.0"
}
},
"is-buffer": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
- "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"dev": true
},
"is-builtin-module": {
@@ -4451,6 +5144,34 @@
"builtin-modules": "1.1.1"
}
},
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
"is-dotfile": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
@@ -4494,14 +5215,33 @@
"dev": true
},
"is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
"dev": true,
"requires": {
"is-extglob": "2.1.1"
}
},
+ "is-my-ip-valid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz",
+ "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==",
+ "dev": true
+ },
+ "is-my-json-valid": {
+ "version": "2.17.2",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz",
+ "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==",
+ "dev": true,
+ "requires": {
+ "generate-function": "2.0.0",
+ "generate-object-property": "1.2.0",
+ "is-my-ip-valid": "1.0.0",
+ "jsonpointer": "4.0.1",
+ "xtend": "4.0.1"
+ }
+ },
"is-number": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
@@ -4511,6 +5251,23 @@
"kind-of": "3.2.2"
}
},
+ "is-odd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
+ "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "dev": true
+ }
+ }
+ },
"is-path-cwd": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
@@ -4518,18 +5275,18 @@
"dev": true
},
"is-path-in-cwd": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
- "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
+ "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
"dev": true,
"requires": {
- "is-path-inside": "1.0.0"
+ "is-path-inside": "1.0.1"
}
},
"is-path-inside": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
- "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
"dev": true,
"requires": {
"path-is-inside": "1.0.2"
@@ -4548,6 +5305,14 @@
"dev": true,
"requires": {
"isobject": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
}
},
"is-posix-bracket": {
@@ -4568,14 +5333,17 @@
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
"dev": true
},
+ "is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
+ "dev": true
+ },
"is-resolvable": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz",
- "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=",
- "dev": true,
- "requires": {
- "tryit": "1.0.3"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+ "dev": true
},
"is-stream": {
"version": "1.1.0",
@@ -4604,6 +5372,12 @@
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
"dev": true
},
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -4623,10 +5397,13 @@
"dev": true
},
"isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
- "dev": true
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
},
"isstream": {
"version": "0.1.2",
@@ -4635,9 +5412,9 @@
"dev": true
},
"jasmine-core": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.7.0.tgz",
- "integrity": "sha1-UP+MT5LY71wLLBuEbdJj7YUVIJE=",
+ "version": "2.99.1",
+ "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
+ "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
"dev": true
},
"jasmine-jquery": {
@@ -4693,7 +5470,7 @@
"integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
"dev": true,
"requires": {
- "argparse": "1.0.9",
+ "argparse": "1.0.10",
"esprima": "2.7.3"
}
},
@@ -4704,12 +5481,6 @@
"dev": true,
"optional": true
},
- "jschardet": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz",
- "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A==",
- "dev": true
- },
"jsesc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
@@ -4743,6 +5514,12 @@
"jsonify": "0.0.0"
}
},
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
@@ -4761,21 +5538,18 @@
"integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
"dev": true
},
- "jsonfile": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
- "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11"
- }
- },
"jsonify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
"integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
"dev": true
},
+ "jsonpointer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
+ "dev": true
+ },
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -4797,46 +5571,40 @@
}
},
"karma": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.0.tgz",
- "integrity": "sha1-b3oaQGRG+i4YfslTmGmPTO5HYmk=",
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz",
+ "integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==",
"dev": true,
"requires": {
- "bluebird": "3.5.0",
- "body-parser": "1.17.2",
+ "bluebird": "3.5.1",
+ "body-parser": "1.18.2",
"chokidar": "1.7.0",
"colors": "1.1.2",
"combine-lists": "1.0.1",
- "connect": "3.6.3",
+ "connect": "3.6.6",
"core-js": "2.5.0",
"di": "0.0.1",
"dom-serialize": "2.2.1",
"expand-braces": "0.1.2",
"glob": "7.1.2",
"graceful-fs": "4.1.11",
- "http-proxy": "1.16.2",
+ "http-proxy": "1.17.0",
"isbinaryfile": "3.0.2",
"lodash": "3.10.1",
"log4js": "0.6.38",
- "mime": "1.3.6",
+ "mime": "1.6.0",
"minimatch": "3.0.4",
"optimist": "0.6.1",
- "qjobs": "1.1.5",
+ "qjobs": "1.2.0",
"range-parser": "1.2.0",
"rimraf": "2.6.1",
"safe-buffer": "5.1.1",
"socket.io": "1.7.3",
"source-map": "0.5.7",
"tmp": "0.0.31",
- "useragent": "2.2.1"
+ "useragent": "2.3.0"
},
"dependencies": {
- "bluebird": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
- "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=",
- "dev": true
- },
"glob": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
@@ -4882,9 +5650,9 @@
"dev": true
},
"karma-jasmine": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.0.tgz",
- "integrity": "sha1-IuTAa/mhguUpTR9wXjczgRuBCs8=",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.1.tgz",
+ "integrity": "sha1-b+hA51oRYAydkehLM8RY4cRqNSk=",
"dev": true
},
"karma-jquery": {
@@ -4900,51 +5668,17 @@
"dev": true
},
"karma-webpack": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.4.tgz",
- "integrity": "sha1-Pi1PSLqUqHjhxmu44a5hKJh6F1s=",
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.13.tgz",
+ "integrity": "sha512-2cyII34jfrAabbI2+4Rk4j95Nazl98FvZQhgSiqKUDarT317rxfv/EdzZ60CyATN4PQxJdO5ucR5bOOXkEVrXw==",
"dev": true,
"requires": {
- "async": "0.9.2",
- "loader-utils": "0.2.17",
- "lodash": "3.10.1",
- "source-map": "0.1.43",
- "webpack-dev-middleware": "1.12.0"
- },
- "dependencies": {
- "async": {
- "version": "0.9.2",
- "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
- "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
- "dev": true
- },
- "loader-utils": {
- "version": "0.2.17",
- "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
- "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
- "dev": true,
- "requires": {
- "big.js": "3.1.3",
- "emojis-list": "2.1.0",
- "json5": "0.5.1",
- "object-assign": "4.1.1"
- }
- },
- "lodash": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
- "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
- "dev": true
- },
- "source-map": {
- "version": "0.1.43",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
- "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
- "dev": true,
- "requires": {
- "amdefine": "1.0.1"
- }
- }
+ "async": "2.6.0",
+ "babel-runtime": "6.26.0",
+ "loader-utils": "1.1.0",
+ "lodash": "4.17.4",
+ "source-map": "0.5.7",
+ "webpack-dev-middleware": "1.12.2"
}
},
"kind-of": {
@@ -4953,22 +5687,13 @@
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
- "is-buffer": "1.1.5"
- }
- },
- "klaw": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
- "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11"
+ "is-buffer": "1.1.6"
}
},
"lazy-cache": {
- "version": "0.2.7",
- "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz",
- "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
"dev": true
},
"lcid": {
@@ -5104,12 +5829,6 @@
"integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
"dev": true
},
- "lodash.cond": {
- "version": "4.5.2",
- "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz",
- "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=",
- "dev": true
- },
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -5218,20 +5937,43 @@
"dev": true
},
"make-dir": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz",
- "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz",
+ "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==",
"dev": true,
"requires": {
- "pify": "2.3.0"
+ "pify": "3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
}
},
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true
+ },
"map-obj": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
"dev": true
},
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "dev": true,
+ "requires": {
+ "object-visit": "1.0.1"
+ }
+ },
"math-expression-evaluator": {
"version": "1.2.17",
"resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
@@ -5246,18 +5988,6 @@
"requires": {
"hash-base": "3.0.4",
"inherits": "2.0.3"
- },
- "dependencies": {
- "hash-base": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
- "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
- "dev": true,
- "requires": {
- "inherits": "2.0.3",
- "safe-buffer": "5.1.1"
- }
- }
}
},
"media-typer": {
@@ -5272,7 +6002,7 @@
"integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
"dev": true,
"requires": {
- "mimic-fn": "1.1.0"
+ "mimic-fn": "1.2.0"
}
},
"memory-fs": {
@@ -5281,7 +6011,7 @@
"integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
"dev": true,
"requires": {
- "errno": "0.1.4",
+ "errno": "0.1.7",
"readable-stream": "2.3.3"
}
},
@@ -5402,7 +6132,7 @@
"normalize-path": "2.1.1",
"object.omit": "2.0.1",
"parse-glob": "3.0.4",
- "regex-cache": "0.4.3"
+ "regex-cache": "0.4.4"
},
"dependencies": {
"is-extglob": {
@@ -5423,9 +6153,9 @@
}
},
"miller-rabin": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz",
- "integrity": "sha1-SmL7HUKTPAVYOYL0xxb2+55sbT0=",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
"dev": true,
"requires": {
"bn.js": "4.11.8",
@@ -5433,9 +6163,9 @@
}
},
"mime": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.6.tgz",
- "integrity": "sha1-WR2E02U6awtKO5343lqoEI5y5eA=",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"dev": true
},
"mime-db": {
@@ -5454,15 +6184,15 @@
}
},
"mimic-fn": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
- "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
"dev": true
},
"minimalistic-assert": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
- "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
"dev": true
},
"minimalistic-crypto-utils": {
@@ -5486,6 +6216,45 @@
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
},
+ "mississippi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz",
+ "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==",
+ "dev": true,
+ "requires": {
+ "concat-stream": "1.6.2",
+ "duplexify": "3.5.4",
+ "end-of-stream": "1.4.1",
+ "flush-write-stream": "1.0.3",
+ "from2": "2.3.0",
+ "parallel-transform": "1.1.0",
+ "pump": "2.0.1",
+ "pumpify": "1.4.0",
+ "stream-each": "1.2.2",
+ "through2": "2.0.3"
+ }
+ },
+ "mixin-deep": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+ "dev": true,
+ "requires": {
+ "for-in": "1.0.2",
+ "is-extendable": "1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "2.0.4"
+ }
+ }
+ }
+ },
"mixin-object": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz",
@@ -5513,6 +6282,25 @@
"minimist": "0.0.8"
}
},
+ "moment": {
+ "version": "2.22.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.1.tgz",
+ "integrity": "sha512-shJkRTSebXvsVqk56I+lkb2latjBs8I+pc2TzWc545y2iFnSjm7Wg0QMh+ZWcdSLQyGEau5jI8ocnmkyTgr9YQ=="
+ },
+ "move-concurrently": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+ "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
+ "dev": true,
+ "requires": {
+ "aproba": "1.1.2",
+ "copy-concurrently": "1.0.5",
+ "fs-write-stream-atomic": "1.0.10",
+ "mkdirp": "0.5.1",
+ "rimraf": "2.6.1",
+ "run-queue": "1.0.3"
+ }
+ },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -5529,7 +6317,48 @@
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz",
"integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=",
- "dev": true
+ "dev": true,
+ "optional": true
+ },
+ "nanomatch": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
+ "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "fragment-cache": "0.2.1",
+ "is-odd": "2.0.0",
+ "is-windows": "1.0.2",
+ "kind-of": "6.0.2",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.2",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
},
"natural-compare": {
"version": "1.4.0",
@@ -5543,14 +6372,17 @@
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
"dev": true
},
- "node-dir": {
- "version": "0.1.17",
- "resolved": "https://registry.npmjs.org/node-dir/-/node-dir-0.1.17.tgz",
- "integrity": "sha1-X1Zl2TNRM1yqvvjxxVRRbPXx5OU=",
- "dev": true,
- "requires": {
- "minimatch": "3.0.4"
- }
+ "neo-async": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz",
+ "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==",
+ "dev": true
+ },
+ "next-tick": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+ "dev": true
},
"node-gyp": {
"version": "3.6.2",
@@ -5596,48 +6428,40 @@
}
},
"node-libs-browser": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz",
- "integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz",
+ "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==",
"dev": true,
"requires": {
"assert": "1.4.1",
- "browserify-zlib": "0.1.4",
+ "browserify-zlib": "0.2.0",
"buffer": "4.9.1",
"console-browserify": "1.1.0",
"constants-browserify": "1.0.0",
- "crypto-browserify": "3.11.1",
- "domain-browser": "1.1.7",
+ "crypto-browserify": "3.12.0",
+ "domain-browser": "1.2.0",
"events": "1.1.1",
- "https-browserify": "0.0.1",
- "os-browserify": "0.2.1",
+ "https-browserify": "1.0.0",
+ "os-browserify": "0.3.0",
"path-browserify": "0.0.0",
"process": "0.11.10",
"punycode": "1.4.1",
"querystring-es3": "0.2.1",
"readable-stream": "2.3.3",
"stream-browserify": "2.0.1",
- "stream-http": "2.7.2",
- "string_decoder": "0.10.31",
- "timers-browserify": "2.0.4",
+ "stream-http": "2.8.1",
+ "string_decoder": "1.0.3",
+ "timers-browserify": "2.0.10",
"tty-browserify": "0.0.0",
"url": "0.11.0",
"util": "0.10.3",
"vm-browserify": "0.0.4"
- },
- "dependencies": {
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
- "dev": true
- }
}
},
"node-sass": {
- "version": "4.5.3",
- "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.5.3.tgz",
- "integrity": "sha1-0JydEXlkEjnRuX/8YjH9zsU+FWg=",
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.0.tgz",
+ "integrity": "sha512-QFHfrZl6lqRU3csypwviz2XLgGNOoWQbo2GOvtsfQqOfL4cy1BtWnhx/XUeAO9LT3ahBzSRXcEO6DdvAH9DzSg==",
"dev": true,
"requires": {
"async-foreach": "0.1.3",
@@ -5652,14 +6476,21 @@
"lodash.mergewith": "4.6.0",
"meow": "3.7.0",
"mkdirp": "0.5.1",
- "nan": "2.6.2",
+ "nan": "2.10.0",
"node-gyp": "3.6.2",
"npmlog": "4.1.2",
- "request": "2.81.0",
+ "request": "2.79.0",
"sass-graph": "2.2.4",
- "stdout-stream": "1.4.0"
+ "stdout-stream": "1.4.0",
+ "true-case-path": "1.0.2"
},
"dependencies": {
+ "caseless": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
+ "dev": true
+ },
"cross-spawn": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
@@ -5683,6 +6514,64 @@
"once": "1.4.0",
"path-is-absolute": "1.0.1"
}
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+ "dev": true,
+ "requires": {
+ "chalk": "1.1.3",
+ "commander": "2.15.1",
+ "is-my-json-valid": "2.17.2",
+ "pinkie-promise": "2.0.1"
+ }
+ },
+ "nan": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
+ "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+ "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
+ "dev": true
+ },
+ "request": {
+ "version": "2.79.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
+ "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "0.6.0",
+ "aws4": "1.6.0",
+ "caseless": "0.11.0",
+ "combined-stream": "1.0.5",
+ "extend": "3.0.1",
+ "forever-agent": "0.6.1",
+ "form-data": "2.1.4",
+ "har-validator": "2.0.6",
+ "hawk": "3.1.3",
+ "http-signature": "1.1.1",
+ "is-typedarray": "1.0.0",
+ "isstream": "0.1.2",
+ "json-stringify-safe": "5.0.1",
+ "mime-types": "2.1.16",
+ "oauth-sign": "0.8.2",
+ "qs": "6.3.2",
+ "stringstream": "0.0.5",
+ "tough-cookie": "2.3.2",
+ "tunnel-agent": "0.4.3",
+ "uuid": "3.1.0"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+ "dev": true
}
}
},
@@ -5796,12 +6685,51 @@
"integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
"dev": true
},
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "0.1.1",
+ "define-property": "0.2.5",
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ }
+ }
+ },
"object-hash": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.1.8.tgz",
"integrity": "sha1-KKZZz5h9lqTavnhgKJ87UybEoDw=",
"dev": true
},
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "requires": {
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
"object.omit": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
@@ -5810,16 +6738,22 @@
"requires": {
"for-own": "0.1.5",
"is-extendable": "0.1.1"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "3.0.1"
},
"dependencies": {
- "for-own": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
- "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
- "dev": true,
- "requires": {
- "for-in": "1.0.2"
- }
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
}
}
},
@@ -5847,7 +6781,7 @@
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
"dev": true,
"requires": {
- "mimic-fn": "1.1.0"
+ "mimic-fn": "1.2.0"
}
},
"optimist": {
@@ -5858,14 +6792,6 @@
"requires": {
"minimist": "0.0.8",
"wordwrap": "0.0.3"
- },
- "dependencies": {
- "wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
- "dev": true
- }
}
},
"optionator": {
@@ -5880,6 +6806,14 @@
"prelude-ls": "1.1.2",
"type-check": "0.3.2",
"wordwrap": "1.0.0"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ }
}
},
"options": {
@@ -5889,9 +6823,9 @@
"dev": true
},
"os-browserify": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz",
- "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=",
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
"dev": true
},
"os-homedir": {
@@ -5932,10 +6866,13 @@
"dev": true
},
"p-limit": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz",
- "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=",
- "dev": true
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz",
+ "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==",
+ "dev": true,
+ "requires": {
+ "p-try": "1.0.0"
+ }
},
"p-locate": {
"version": "2.0.0",
@@ -5943,26 +6880,43 @@
"integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
"dev": true,
"requires": {
- "p-limit": "1.1.0"
+ "p-limit": "1.2.0"
}
},
- "pako": {
- "version": "0.2.9",
- "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
- "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
"dev": true
},
- "parse-asn1": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
- "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
+ "pako": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
+ "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==",
+ "dev": true
+ },
+ "parallel-transform": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz",
+ "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
"dev": true,
"requires": {
- "asn1.js": "4.9.1",
- "browserify-aes": "1.0.6",
- "create-hash": "1.1.3",
- "evp_bytestokey": "1.0.2",
- "pbkdf2": "3.0.13"
+ "cyclist": "0.2.2",
+ "inherits": "2.0.3",
+ "readable-stream": "2.3.3"
+ }
+ },
+ "parse-asn1": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
+ "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
+ "dev": true,
+ "requires": {
+ "asn1.js": "4.10.1",
+ "browserify-aes": "1.2.0",
+ "create-hash": "1.2.0",
+ "evp_bytestokey": "1.0.3",
+ "pbkdf2": "3.0.16"
}
},
"parse-glob": {
@@ -6031,9 +6985,15 @@
}
},
"parseurl": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz",
- "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+ "dev": true
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
"dev": true
},
"path-browserify": {
@@ -6042,6 +7002,12 @@
"integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
"dev": true
},
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+ "dev": true
+ },
"path-exists": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
@@ -6073,25 +7039,33 @@
"dev": true
},
"path-type": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
- "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
"dev": true,
"requires": {
- "pify": "2.3.0"
+ "pify": "3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
}
},
"pbkdf2": {
- "version": "3.0.13",
- "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.13.tgz",
- "integrity": "sha512-+dCHxDH+djNtjgWmvVC/my3SYBAKpKNqKSjLkp+GtWWYe4XPE+e/PSD2aCanlEZZnqPk2uekTKNC/ccbwd2X2Q==",
+ "version": "3.0.16",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz",
+ "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==",
"dev": true,
"requires": {
- "create-hash": "1.1.3",
- "create-hmac": "1.1.6",
- "ripemd160": "2.0.1",
+ "create-hash": "1.2.0",
+ "create-hmac": "1.1.7",
+ "ripemd160": "2.0.2",
"safe-buffer": "5.1.1",
- "sha.js": "2.4.8"
+ "sha.js": "2.4.11"
}
},
"performance-now": {
@@ -6136,15 +7110,21 @@
"integrity": "sha1-F78QIbM6E0fESKQ3ff1ExUWtGgc="
},
"pluralize": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-4.0.0.tgz",
- "integrity": "sha1-WbcIwcAZCi9pLxx2GMRGsFL9F2I=",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
+ "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
+ "dev": true
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
"dev": true
},
"postcss": {
- "version": "5.2.17",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz",
- "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=",
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
"dev": true,
"requires": {
"chalk": "1.1.3",
@@ -6170,7 +7150,7 @@
"integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=",
"dev": true,
"requires": {
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-message-helpers": "2.0.0",
"reduce-css-calc": "1.3.0"
}
@@ -6182,7 +7162,7 @@
"dev": true,
"requires": {
"colormin": "1.1.2",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0"
}
},
@@ -6192,7 +7172,7 @@
"integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=",
"dev": true,
"requires": {
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0"
}
},
@@ -6202,7 +7182,7 @@
"integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=",
"dev": true,
"requires": {
- "postcss": "5.2.17"
+ "postcss": "5.2.18"
}
},
"postcss-discard-duplicates": {
@@ -6211,7 +7191,7 @@
"integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=",
"dev": true,
"requires": {
- "postcss": "5.2.17"
+ "postcss": "5.2.18"
}
},
"postcss-discard-empty": {
@@ -6220,7 +7200,7 @@
"integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=",
"dev": true,
"requires": {
- "postcss": "5.2.17"
+ "postcss": "5.2.18"
}
},
"postcss-discard-overridden": {
@@ -6229,7 +7209,7 @@
"integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=",
"dev": true,
"requires": {
- "postcss": "5.2.17"
+ "postcss": "5.2.18"
}
},
"postcss-discard-unused": {
@@ -6238,7 +7218,7 @@
"integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=",
"dev": true,
"requires": {
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"uniqs": "2.0.0"
}
},
@@ -6248,7 +7228,7 @@
"integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=",
"dev": true,
"requires": {
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"uniqid": "4.1.1"
}
},
@@ -6259,7 +7239,7 @@
"dev": true,
"requires": {
"has": "1.0.1",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0"
}
},
@@ -6269,7 +7249,7 @@
"integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=",
"dev": true,
"requires": {
- "postcss": "5.2.17"
+ "postcss": "5.2.18"
}
},
"postcss-merge-rules": {
@@ -6280,9 +7260,9 @@
"requires": {
"browserslist": "1.7.7",
"caniuse-api": "1.6.1",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-selector-parser": "2.2.3",
- "vendors": "1.0.1"
+ "vendors": "1.0.2"
}
},
"postcss-message-helpers": {
@@ -6298,7 +7278,7 @@
"dev": true,
"requires": {
"object-assign": "4.1.1",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0"
}
},
@@ -6308,7 +7288,7 @@
"integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=",
"dev": true,
"requires": {
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0"
}
},
@@ -6319,7 +7299,7 @@
"dev": true,
"requires": {
"alphanum-sort": "1.0.2",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0",
"uniqs": "2.0.0"
}
@@ -6332,63 +7312,69 @@
"requires": {
"alphanum-sort": "1.0.2",
"has": "1.0.1",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-selector-parser": "2.2.3"
}
},
"postcss-modules-extract-imports": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz",
- "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz",
+ "integrity": "sha1-ZhQOzs447wa/DT41XWm/WdFB6oU=",
"dev": true,
"requires": {
- "postcss": "6.0.9"
+ "postcss": "6.0.22"
},
"dependencies": {
"ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
- "color-convert": "1.9.0"
+ "color-convert": "1.9.1"
}
},
"chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"dev": true,
"requires": {
- "ansi-styles": "3.2.0",
+ "ansi-styles": "3.2.1",
"escape-string-regexp": "1.0.5",
- "supports-color": "4.2.1"
+ "supports-color": "5.4.0"
}
},
"has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"postcss": {
- "version": "6.0.9",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.9.tgz",
- "integrity": "sha512-bBE2AHNEBhF23TfET6AA/lFP8ah+qHOZoFJEflFG+HgvVLdTmMOrocx/4LVVDIn3w6jUssw1q2Exk1cc9UOI8w==",
+ "version": "6.0.22",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz",
+ "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==",
"dev": true,
"requires": {
- "chalk": "2.1.0",
- "source-map": "0.5.7",
- "supports-color": "4.2.1"
+ "chalk": "2.4.1",
+ "source-map": "0.6.1",
+ "supports-color": "5.4.0"
}
},
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
"supports-color": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz",
- "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==",
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
"dev": true,
"requires": {
- "has-flag": "2.0.0"
+ "has-flag": "3.0.0"
}
}
}
@@ -6400,53 +7386,59 @@
"dev": true,
"requires": {
"css-selector-tokenizer": "0.7.0",
- "postcss": "6.0.9"
+ "postcss": "6.0.22"
},
"dependencies": {
"ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
- "color-convert": "1.9.0"
+ "color-convert": "1.9.1"
}
},
"chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"dev": true,
"requires": {
- "ansi-styles": "3.2.0",
+ "ansi-styles": "3.2.1",
"escape-string-regexp": "1.0.5",
- "supports-color": "4.2.1"
+ "supports-color": "5.4.0"
}
},
"has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"postcss": {
- "version": "6.0.9",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.9.tgz",
- "integrity": "sha512-bBE2AHNEBhF23TfET6AA/lFP8ah+qHOZoFJEflFG+HgvVLdTmMOrocx/4LVVDIn3w6jUssw1q2Exk1cc9UOI8w==",
+ "version": "6.0.22",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz",
+ "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==",
"dev": true,
"requires": {
- "chalk": "2.1.0",
- "source-map": "0.5.7",
- "supports-color": "4.2.1"
+ "chalk": "2.4.1",
+ "source-map": "0.6.1",
+ "supports-color": "5.4.0"
}
},
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
"supports-color": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz",
- "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==",
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
"dev": true,
"requires": {
- "has-flag": "2.0.0"
+ "has-flag": "3.0.0"
}
}
}
@@ -6458,53 +7450,59 @@
"dev": true,
"requires": {
"css-selector-tokenizer": "0.7.0",
- "postcss": "6.0.9"
+ "postcss": "6.0.22"
},
"dependencies": {
"ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
- "color-convert": "1.9.0"
+ "color-convert": "1.9.1"
}
},
"chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"dev": true,
"requires": {
- "ansi-styles": "3.2.0",
+ "ansi-styles": "3.2.1",
"escape-string-regexp": "1.0.5",
- "supports-color": "4.2.1"
+ "supports-color": "5.4.0"
}
},
"has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"postcss": {
- "version": "6.0.9",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.9.tgz",
- "integrity": "sha512-bBE2AHNEBhF23TfET6AA/lFP8ah+qHOZoFJEflFG+HgvVLdTmMOrocx/4LVVDIn3w6jUssw1q2Exk1cc9UOI8w==",
+ "version": "6.0.22",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz",
+ "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==",
"dev": true,
"requires": {
- "chalk": "2.1.0",
- "source-map": "0.5.7",
- "supports-color": "4.2.1"
+ "chalk": "2.4.1",
+ "source-map": "0.6.1",
+ "supports-color": "5.4.0"
}
},
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
"supports-color": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz",
- "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==",
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
"dev": true,
"requires": {
- "has-flag": "2.0.0"
+ "has-flag": "3.0.0"
}
}
}
@@ -6516,53 +7514,59 @@
"dev": true,
"requires": {
"icss-replace-symbols": "1.1.0",
- "postcss": "6.0.9"
+ "postcss": "6.0.22"
},
"dependencies": {
"ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
- "color-convert": "1.9.0"
+ "color-convert": "1.9.1"
}
},
"chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"dev": true,
"requires": {
- "ansi-styles": "3.2.0",
+ "ansi-styles": "3.2.1",
"escape-string-regexp": "1.0.5",
- "supports-color": "4.2.1"
+ "supports-color": "5.4.0"
}
},
"has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"postcss": {
- "version": "6.0.9",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.9.tgz",
- "integrity": "sha512-bBE2AHNEBhF23TfET6AA/lFP8ah+qHOZoFJEflFG+HgvVLdTmMOrocx/4LVVDIn3w6jUssw1q2Exk1cc9UOI8w==",
+ "version": "6.0.22",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz",
+ "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==",
"dev": true,
"requires": {
- "chalk": "2.1.0",
- "source-map": "0.5.7",
- "supports-color": "4.2.1"
+ "chalk": "2.4.1",
+ "source-map": "0.6.1",
+ "supports-color": "5.4.0"
}
},
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
"supports-color": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz",
- "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==",
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
"dev": true,
"requires": {
- "has-flag": "2.0.0"
+ "has-flag": "3.0.0"
}
}
}
@@ -6573,7 +7577,7 @@
"integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=",
"dev": true,
"requires": {
- "postcss": "5.2.17"
+ "postcss": "5.2.18"
}
},
"postcss-normalize-url": {
@@ -6584,7 +7588,7 @@
"requires": {
"is-absolute-url": "2.1.0",
"normalize-url": "1.9.1",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0"
}
},
@@ -6594,7 +7598,7 @@
"integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=",
"dev": true,
"requires": {
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0"
}
},
@@ -6604,7 +7608,7 @@
"integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=",
"dev": true,
"requires": {
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0"
}
},
@@ -6614,7 +7618,7 @@
"integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=",
"dev": true,
"requires": {
- "postcss": "5.2.17"
+ "postcss": "5.2.18"
}
},
"postcss-reduce-transforms": {
@@ -6624,7 +7628,7 @@
"dev": true,
"requires": {
"has": "1.0.1",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0"
}
},
@@ -6646,7 +7650,7 @@
"dev": true,
"requires": {
"is-svg": "2.1.0",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"postcss-value-parser": "3.3.0",
"svgo": "0.7.2"
}
@@ -6658,7 +7662,7 @@
"dev": true,
"requires": {
"alphanum-sort": "1.0.2",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"uniqs": "2.0.0"
}
},
@@ -6675,7 +7679,7 @@
"dev": true,
"requires": {
"has": "1.0.1",
- "postcss": "5.2.17",
+ "postcss": "5.2.18",
"uniqs": "2.0.0"
}
},
@@ -6721,10 +7725,16 @@
"integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
"dev": true
},
+ "promise-inflight": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+ "dev": true
+ },
"prr": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz",
- "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
"dev": true
},
"pseudomap": {
@@ -6734,16 +7744,37 @@
"dev": true
},
"public-encrypt": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
- "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz",
+ "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==",
"dev": true,
"requires": {
"bn.js": "4.11.8",
"browserify-rsa": "4.0.1",
- "create-hash": "1.1.3",
- "parse-asn1": "5.1.0",
- "randombytes": "2.0.5"
+ "create-hash": "1.2.0",
+ "parse-asn1": "5.1.1",
+ "randombytes": "2.0.6"
+ }
+ },
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "1.4.1",
+ "once": "1.4.0"
+ }
+ },
+ "pumpify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.4.0.tgz",
+ "integrity": "sha512-2kmNR9ry+Pf45opRVirpNuIFotsxUGLaYqxIwuR77AYrYRMuFCz9eryHBS52L360O+NcR383CL4QYlMKPq4zYA==",
+ "dev": true,
+ "requires": {
+ "duplexify": "3.5.4",
+ "inherits": "2.0.3",
+ "pump": "2.0.1"
}
},
"punycode": {
@@ -6753,15 +7784,15 @@
"dev": true
},
"q": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz",
- "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=",
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
"dev": true
},
"qjobs": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.1.5.tgz",
- "integrity": "sha1-ZZ3p8s+NzCehSBJ28gU3cnI4LnM=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
+ "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
"dev": true
},
"qs": {
@@ -6817,7 +7848,7 @@
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
- "is-buffer": "1.1.5"
+ "is-buffer": "1.1.6"
}
}
}
@@ -6828,20 +7859,30 @@
"integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
"dev": true,
"requires": {
- "is-buffer": "1.1.5"
+ "is-buffer": "1.1.6"
}
}
}
},
"randombytes": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz",
- "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==",
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
+ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
"dev": true,
"requires": {
"safe-buffer": "5.1.1"
}
},
+ "randomfill": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "2.0.6",
+ "safe-buffer": "5.1.1"
+ }
+ },
"range-parser": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
@@ -6849,20 +7890,39 @@
"dev": true
},
"raw-body": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz",
- "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=",
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
+ "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
"dev": true,
"requires": {
- "bytes": "2.4.0",
- "iconv-lite": "0.4.15",
+ "bytes": "3.0.0",
+ "http-errors": "1.6.2",
+ "iconv-lite": "0.4.19",
"unpipe": "1.0.0"
},
"dependencies": {
- "iconv-lite": {
- "version": "0.4.15",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
- "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=",
+ "depd": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
+ "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
+ "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
+ "dev": true,
+ "requires": {
+ "depd": "1.1.1",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.0.3",
+ "statuses": "1.5.0"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
+ "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=",
"dev": true
}
}
@@ -6876,6 +7936,17 @@
"load-json-file": "2.0.0",
"normalize-package-data": "2.4.0",
"path-type": "2.0.0"
+ },
+ "dependencies": {
+ "path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "dev": true,
+ "requires": {
+ "pify": "2.3.0"
+ }
+ }
}
},
"read-pkg-up": {
@@ -6985,15 +8056,30 @@
}
},
"regex-cache": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz",
- "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=",
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
+ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
"dev": true,
"requires": {
- "is-equal-shallow": "0.1.3",
- "is-primitive": "2.0.0"
+ "is-equal-shallow": "0.1.3"
}
},
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "3.0.2",
+ "safe-regex": "1.1.0"
+ }
+ },
+ "regexpp": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
+ "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==",
+ "dev": true
+ },
"regexpu-core": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
@@ -7114,9 +8200,9 @@
"dev": true
},
"resolve": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz",
- "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==",
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz",
+ "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
"dev": true,
"requires": {
"path-parse": "1.0.5"
@@ -7128,6 +8214,12 @@
"integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
"dev": true
},
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "dev": true
+ },
"restore-cursor": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
@@ -7138,6 +8230,12 @@
"signal-exit": "3.0.2"
}
},
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true
+ },
"right-align": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
@@ -7173,12 +8271,12 @@
}
},
"ripemd160": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
- "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
"dev": true,
"requires": {
- "hash-base": "2.0.2",
+ "hash-base": "3.0.4",
"inherits": "2.0.3"
}
},
@@ -7191,6 +8289,15 @@
"is-promise": "2.1.0"
}
},
+ "run-queue": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+ "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
+ "dev": true,
+ "requires": {
+ "aproba": "1.1.2"
+ }
+ },
"rx-lite": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
@@ -7212,6 +8319,15 @@
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
"dev": true
},
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "requires": {
+ "ret": "0.1.15"
+ }
+ },
"sass-graph": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
@@ -7241,15 +8357,15 @@
}
},
"sass-loader": {
- "version": "6.0.6",
- "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.6.tgz",
- "integrity": "sha512-c3/Zc+iW+qqDip6kXPYLEgsAu2lf4xz0EZDplB7EmSUMda12U1sGJPetH55B/j9eu0bTtKzKlNPWWyYC7wFNyQ==",
+ "version": "6.0.7",
+ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.7.tgz",
+ "integrity": "sha512-JoiyD00Yo1o61OJsoP2s2kb19L1/Y2p3QFcCdWdF6oomBGKVYuZyqHWemRBfQ2uGYsk+CH3eCguXNfpjzlcpaA==",
"dev": true,
"requires": {
- "async": "2.5.0",
- "clone-deep": "0.3.0",
+ "clone-deep": "2.0.2",
"loader-utils": "1.1.0",
"lodash.tail": "4.1.1",
+ "neo-async": "2.5.1",
"pify": "3.0.0"
},
"dependencies": {
@@ -7303,6 +8419,12 @@
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
"dev": true
},
+ "serialize-javascript": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz",
+ "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==",
+ "dev": true
+ },
"set-blocking": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
@@ -7315,6 +8437,29 @@
"integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
"dev": true
},
+ "set-value": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "split-string": "3.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
@@ -7322,40 +8467,37 @@
"dev": true
},
"setprototypeof": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
- "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
"dev": true
},
"sha.js": {
- "version": "2.4.8",
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz",
- "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=",
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"dev": true,
"requires": {
- "inherits": "2.0.3"
+ "inherits": "2.0.3",
+ "safe-buffer": "5.1.1"
}
},
"shallow-clone": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz",
- "integrity": "sha1-WQnodLp3EG1zrEFM/sH/yofZcGA=",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz",
+ "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==",
"dev": true,
"requires": {
"is-extendable": "0.1.1",
- "kind-of": "2.0.1",
- "lazy-cache": "0.2.7",
+ "kind-of": "5.1.0",
"mixin-object": "2.0.1"
},
"dependencies": {
"kind-of": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz",
- "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=",
- "dev": true,
- "requires": {
- "is-buffer": "1.1.5"
- }
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
}
}
},
@@ -7387,10 +8529,121 @@
"dev": true
},
"slice-ansi": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
- "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
- "dev": true
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
+ "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "2.0.0"
+ }
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "requires": {
+ "base": "0.11.2",
+ "debug": "2.6.8",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "map-cache": "0.2.2",
+ "source-map": "0.5.7",
+ "source-map-resolve": "0.5.1",
+ "use": "3.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "requires": {
+ "define-property": "1.0.0",
+ "isobject": "3.0.1",
+ "snapdragon-util": "3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
},
"sntp": {
"version": "1.0.9",
@@ -7564,15 +8817,34 @@
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
},
+ "source-map-resolve": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz",
+ "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==",
+ "dev": true,
+ "requires": {
+ "atob": "2.1.1",
+ "decode-uri-component": "0.2.0",
+ "resolve-url": "0.2.1",
+ "source-map-url": "0.4.0",
+ "urix": "0.1.0"
+ }
+ },
"source-map-support": {
- "version": "0.4.16",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.16.tgz",
- "integrity": "sha512-A6vlydY7H/ljr4L2UOhDSajQdZQ6dMD7cLH0pzwcmwLyc9u8PNI4WGtnfDDzX7uzGL6c/T+ORL97Zlh+S4iOrg==",
+ "version": "0.4.18",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
"dev": true,
"requires": {
"source-map": "0.5.7"
}
},
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+ "dev": true
+ },
"spdx-correct": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
@@ -7594,6 +8866,15 @@
"integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
"dev": true
},
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "3.0.2"
+ }
+ },
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -7624,10 +8905,40 @@
}
}
},
+ "ssri": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz",
+ "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "requires": {
+ "define-property": "0.2.5",
+ "object-copy": "0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ }
+ }
+ },
"statuses": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
- "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
"dev": true
},
"stdout-stream": {
@@ -7649,10 +8960,20 @@
"readable-stream": "2.3.3"
}
},
+ "stream-each": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz",
+ "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "1.4.1",
+ "stream-shift": "1.0.0"
+ }
+ },
"stream-http": {
- "version": "2.7.2",
- "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz",
- "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==",
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.1.tgz",
+ "integrity": "sha512-cQ0jo17BLca2r0GfRdZKYAGLU6JRoIWxqSOakUMuKOT6MOK7AAlE856L33QuDmAy/eeOrhLee3dZKX0Uadu93A==",
"dev": true,
"requires": {
"builtin-status-codes": "3.0.0",
@@ -7662,6 +8983,12 @@
"xtend": "4.0.1"
}
},
+ "stream-shift": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
+ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
+ "dev": true
+ },
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@@ -7778,39 +9105,74 @@
}
},
"table": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/table/-/table-4.0.1.tgz",
- "integrity": "sha1-qBFsEz+sLGH0pCCrbN9cTWHw5DU=",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
+ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
"dev": true,
"requires": {
- "ajv": "4.11.8",
- "ajv-keywords": "1.5.1",
- "chalk": "1.1.3",
+ "ajv": "5.5.2",
+ "ajv-keywords": "2.1.1",
+ "chalk": "2.4.1",
"lodash": "4.17.4",
- "slice-ansi": "0.0.4",
+ "slice-ansi": "1.0.0",
"string-width": "2.1.1"
},
"dependencies": {
"ajv": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
- "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"dev": true,
"requires": {
"co": "4.6.0",
- "json-stable-stringify": "1.0.1"
+ "fast-deep-equal": "1.0.0",
+ "fast-json-stable-stringify": "2.0.0",
+ "json-schema-traverse": "0.3.1"
+ }
+ },
+ "ajv-keywords": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
+ "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "1.9.1"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "3.2.1",
+ "escape-string-regexp": "1.0.5",
+ "supports-color": "5.4.0"
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "dev": true,
+ "requires": {
+ "has-flag": "3.0.0"
}
}
}
},
- "tablesorter": {
- "version": "2.28.15",
- "resolved": "https://registry.npmjs.org/tablesorter/-/tablesorter-2.28.15.tgz",
- "integrity": "sha512-CDTWhB9EkIEvbMhWuhE9oDHrgPJXMYYd8jX9NCUaVFRpLghz43B7s1wBV7mP9v3BfQrgXB+HXFhdUiukB8ZiZg==",
- "requires": {
- "jquery": "3.2.1"
- }
- },
"tapable": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz",
@@ -7840,6 +9202,16 @@
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
+ "through2": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "2.3.3",
+ "xtend": "4.0.1"
+ }
+ },
"time-stamp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.0.0.tgz",
@@ -7851,13 +9223,13 @@
"resolved": "https://registry.npmjs.org/timeago.js/-/timeago.js-3.0.2.tgz",
"integrity": "sha1-MqZ+fA2IfqQspYjTquJvd95edsw=",
"requires": {
- "@types/jquery": "2.0.48"
+ "@types/jquery": "2.0.49"
}
},
"timers-browserify": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz",
- "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==",
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz",
+ "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==",
"dev": true,
"requires": {
"setimmediate": "1.0.5"
@@ -7895,6 +9267,48 @@
"integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
"dev": true
},
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "requires": {
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "regex-not": "1.0.2",
+ "safe-regex": "1.1.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ }
+ }
+ }
+ },
"tough-cookie": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz",
@@ -7916,11 +9330,14 @@
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
"dev": true
},
- "tryit": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
- "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=",
- "dev": true
+ "true-case-path": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz",
+ "integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=",
+ "dev": true,
+ "requires": {
+ "glob": "6.0.4"
+ }
},
"tty-browserify": {
"version": "0.0.0",
@@ -7954,13 +9371,30 @@
}
},
"type-is": {
- "version": "1.6.15",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
- "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
+ "version": "1.6.16",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
"dev": true,
"requires": {
"media-typer": "0.3.0",
- "mime-types": "2.1.16"
+ "mime-types": "2.1.18"
+ },
+ "dependencies": {
+ "mime-db": {
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+ "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.18",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.33.0"
+ }
+ }
}
},
"typedarray": {
@@ -8032,7 +9466,7 @@
"requires": {
"source-map": "0.5.7",
"uglify-js": "2.8.29",
- "webpack-sources": "1.0.1"
+ "webpack-sources": "1.1.0"
}
},
"ultron": {
@@ -8041,6 +9475,41 @@
"integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=",
"dev": true
},
+ "union-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+ "dev": true,
+ "requires": {
+ "arr-union": "3.1.0",
+ "get-value": "2.0.6",
+ "is-extendable": "0.1.1",
+ "set-value": "0.4.3"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "set-value": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-extendable": "0.1.1",
+ "is-plain-object": "2.0.4",
+ "to-object-path": "0.3.0"
+ }
+ }
+ }
+ },
"uniq": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
@@ -8062,12 +9531,105 @@
"integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
"dev": true
},
+ "unique-filename": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz",
+ "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=",
+ "dev": true,
+ "requires": {
+ "unique-slug": "2.0.0"
+ }
+ },
+ "unique-slug": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz",
+ "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "0.1.4"
+ }
+ },
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
"dev": true
},
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "requires": {
+ "has-value": "0.3.1",
+ "isobject": "3.0.1"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "requires": {
+ "get-value": "2.0.6",
+ "has-values": "0.1.4",
+ "isobject": "2.1.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "upath": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.5.tgz",
+ "integrity": "sha512-qbKn90aDQ0YEwvXoLqj0oiuUYroLX2lVHZ+b+xwjozFasAOC4GneDq5+OaIG5Zj+jFmbz/uO+f7a9qxjktJQww==",
+ "dev": true
+ },
+ "uri-js": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz",
+ "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=",
+ "dev": true,
+ "requires": {
+ "punycode": "2.1.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
+ "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=",
+ "dev": true
+ }
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "dev": true
+ },
"url": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
@@ -8086,24 +9648,33 @@
}
}
},
- "useragent": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.2.1.tgz",
- "integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=",
+ "use": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz",
+ "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==",
"dev": true,
"requires": {
- "lru-cache": "2.2.4",
- "tmp": "0.0.31"
+ "kind-of": "6.0.2"
},
"dependencies": {
- "lru-cache": {
- "version": "2.2.4",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.2.4.tgz",
- "integrity": "sha1-bGWGGb7PFAMdDQtZSxYELOTcBj0=",
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
"dev": true
}
}
},
+ "useragent": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz",
+ "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "4.1.1",
+ "tmp": "0.0.31"
+ }
+ },
"util": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
@@ -8128,9 +9699,9 @@
"dev": true
},
"utils-merge": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
- "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
"dev": true
},
"uuid": {
@@ -8150,9 +9721,9 @@
}
},
"vendors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.1.tgz",
- "integrity": "sha1-N61zyO5Bf7PVgOeFMSMH0nSEfyI=",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz",
+ "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==",
"dev": true
},
"verror": {
@@ -8190,51 +9761,384 @@
"dev": true
},
"watchpack": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz",
- "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
+ "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==",
"dev": true,
"requires": {
- "async": "2.5.0",
- "chokidar": "1.7.0",
- "graceful-fs": "4.1.11"
+ "chokidar": "2.0.3",
+ "graceful-fs": "4.1.11",
+ "neo-async": "2.5.1"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "3.1.10",
+ "normalize-path": "2.1.1"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "1.1.0",
+ "array-unique": "0.3.2",
+ "extend-shallow": "2.0.1",
+ "fill-range": "4.0.0",
+ "isobject": "3.0.1",
+ "repeat-element": "1.1.2",
+ "snapdragon": "0.8.2",
+ "snapdragon-node": "2.1.1",
+ "split-string": "3.1.0",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "chokidar": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz",
+ "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==",
+ "dev": true,
+ "requires": {
+ "anymatch": "2.0.0",
+ "async-each": "1.0.1",
+ "braces": "2.3.2",
+ "fsevents": "1.1.2",
+ "glob-parent": "3.1.0",
+ "inherits": "2.0.3",
+ "is-binary-path": "1.0.1",
+ "is-glob": "4.0.0",
+ "normalize-path": "2.1.1",
+ "path-is-absolute": "1.0.1",
+ "readdirp": "2.1.0",
+ "upath": "1.0.5"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.8",
+ "define-property": "0.2.5",
+ "extend-shallow": "2.0.1",
+ "posix-character-classes": "0.1.1",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.2",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "0.1.6"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "0.1.6",
+ "is-data-descriptor": "0.1.4",
+ "kind-of": "5.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "0.3.2",
+ "define-property": "1.0.0",
+ "expand-brackets": "2.1.4",
+ "extend-shallow": "2.0.1",
+ "fragment-cache": "0.2.1",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.2",
+ "to-regex": "3.0.2"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "1.0.2"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "2.0.1",
+ "is-number": "3.0.0",
+ "repeat-string": "1.6.1",
+ "to-regex-range": "2.1.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "0.1.1"
+ }
+ }
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "3.1.0",
+ "path-dirname": "1.0.2"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "2.1.1"
+ }
+ }
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "1.0.0",
+ "is-data-descriptor": "1.0.0",
+ "kind-of": "6.0.2"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "3.2.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "1.1.6"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "4.0.0",
+ "array-unique": "0.3.2",
+ "braces": "2.3.2",
+ "define-property": "2.0.2",
+ "extend-shallow": "3.0.2",
+ "extglob": "2.0.4",
+ "fragment-cache": "0.2.1",
+ "kind-of": "6.0.2",
+ "nanomatch": "1.2.9",
+ "object.pick": "1.3.0",
+ "regex-not": "1.0.2",
+ "snapdragon": "0.8.2",
+ "to-regex": "3.0.2"
+ }
+ }
}
},
"webpack": {
- "version": "3.5.5",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.5.5.tgz",
- "integrity": "sha512-qeUx4nIbeLL53qqNTs3kObPBMkUVDrOjEfp/hTvMlx21qL2MsGNr8/tXCoX/lS12dLl9qtZaXv2qfBEctPScDg==",
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.11.0.tgz",
+ "integrity": "sha512-3kOFejWqj5ISpJk4Qj/V7w98h9Vl52wak3CLiw/cDOfbVTq7FeoZ0SdoHHY9PYlHr50ZS42OfvzE2vB4nncKQg==",
"dev": true,
"requires": {
- "acorn": "5.1.1",
+ "acorn": "5.5.3",
"acorn-dynamic-import": "2.0.2",
- "ajv": "5.2.2",
- "ajv-keywords": "2.1.0",
- "async": "2.5.0",
+ "ajv": "6.4.0",
+ "ajv-keywords": "3.2.0",
+ "async": "2.6.0",
"enhanced-resolve": "3.4.1",
"escope": "3.6.0",
- "interpret": "1.0.3",
+ "interpret": "1.1.0",
"json-loader": "0.5.7",
"json5": "0.5.1",
"loader-runner": "2.3.0",
"loader-utils": "1.1.0",
"memory-fs": "0.4.1",
"mkdirp": "0.5.1",
- "node-libs-browser": "2.0.0",
+ "node-libs-browser": "2.1.0",
"source-map": "0.5.7",
- "supports-color": "4.2.1",
+ "supports-color": "4.5.0",
"tapable": "0.2.8",
"uglifyjs-webpack-plugin": "0.4.6",
- "watchpack": "1.4.0",
- "webpack-sources": "1.0.1",
+ "watchpack": "1.6.0",
+ "webpack-sources": "1.1.0",
"yargs": "8.0.2"
},
"dependencies": {
- "ajv-keywords": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz",
- "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=",
- "dev": true
+ "ajv": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz",
+ "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "1.0.0",
+ "fast-json-stable-stringify": "2.0.0",
+ "json-schema-traverse": "0.3.1",
+ "uri-js": "3.0.2"
+ }
},
"camelcase": {
"version": "4.1.0",
@@ -8260,9 +10164,9 @@
}
},
"supports-color": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz",
- "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
"dev": true,
"requires": {
"has-flag": "2.0.0"
@@ -8307,26 +10211,34 @@
}
},
"webpack-dev-middleware": {
- "version": "1.12.0",
- "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz",
- "integrity": "sha1-007++y7dp+HTtdvgcolRMhllFwk=",
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz",
+ "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==",
"dev": true,
"requires": {
"memory-fs": "0.4.1",
- "mime": "1.3.6",
+ "mime": "1.6.0",
"path-is-absolute": "1.0.1",
"range-parser": "1.2.0",
"time-stamp": "2.0.0"
}
},
"webpack-sources": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.1.tgz",
- "integrity": "sha512-05tMxipUCwHqYaVS8xc7sYPTly8PzXayRCB4dTxLhWTqlKUiwH6ezmEe0OSreL1c30LAuA3Zqmc+uEBUGFJDjw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz",
+ "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==",
"dev": true,
"requires": {
"source-list-map": "2.0.0",
- "source-map": "0.5.7"
+ "source-map": "0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
}
},
"whet.extend": {
@@ -8388,9 +10300,9 @@
"dev": true
},
"wordwrap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
"dev": true
},
"wrap-ansi": {
diff --git a/lib/assets/package.json b/lib/assets/package.json
index 36c3c16..730cfef 100644
--- a/lib/assets/package.json
+++ b/lib/assets/package.json
@@ -34,31 +34,31 @@
"tinymce": "4.6.5"
},
"devDependencies": {
- "babel-core": "^6.25.0",
- "babel-loader": "^7.1.1",
+ "babel-core": "^6.26.3",
+ "babel-loader": "^7.1.4",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
- "copy-webpack-plugin": "^4.0.1",
- "css-loader": "^0.28.4",
+ "copy-webpack-plugin": "^4.5.1",
+ "css-loader": "^0.28.11",
"eslint": "^4.10.0",
"eslint-config-airbnb-base": "^11.3.2",
"eslint-loader": "^1.9.0",
"eslint-plugin-import": "^2.8.0",
- "extract-text-webpack-plugin": "^3.0.0",
+ "extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^0.11.2",
- "jasmine-core": "^2.7.0",
+ "jasmine-core": "^2.99.1",
"jasmine-jquery": "^2.1.1",
- "karma": "^1.7.0",
+ "karma": "^1.7.1",
"karma-chrome-launcher": "^2.2.0",
"karma-fixture": "^0.2.6",
"karma-html2js-preprocessor": "^1.1.0",
- "karma-jasmine": "^1.1.0",
+ "karma-jasmine": "^1.1.1",
"karma-jquery": "^0.2.2",
"karma-json-fixtures-preprocessor": "0.0.6",
- "karma-webpack": "^2.0.4",
- "node-sass": "^4.5.3",
- "sass-loader": "^6.0.6",
+ "karma-webpack": "^2.0.13",
+ "node-sass": "^4.9.0",
+ "sass-loader": "^6.0.7",
"style-loader": "^0.18.2",
- "webpack": "^3.5.4"
+ "webpack": "^3.11.0"
}
}
diff --git a/lib/assets/stylesheets/overrides.scss b/lib/assets/stylesheets/overrides.scss
index d0801b7..1f833b3 100644
--- a/lib/assets/stylesheets/overrides.scss
+++ b/lib/assets/stylesheets/overrides.scss
@@ -502,6 +502,12 @@
}
}
+/* Templates page table pre-defined filters */
+.template-table-filters .navbar-nav > li > a {
+ color: $grey;
+ padding: 5px 15px 5px 5px;
+}
+
/* Sharp edges */
#app-navbar,
#org-navbar,
diff --git a/lib/tasks/notifications.rake b/lib/tasks/notifications.rake
new file mode 100644
index 0000000..c536e06
--- /dev/null
+++ b/lib/tasks/notifications.rake
@@ -0,0 +1,7 @@
+namespace :notifications do
+ desc "Create some notifications types"
+ task create_types: :environment do
+ NotificationType.create(name: 'global')
+ end
+
+end
diff --git a/lib/tasks/upgrade.rake b/lib/tasks/upgrade.rake
index eb96b99..c0723dd 100644
--- a/lib/tasks/upgrade.rake
+++ b/lib/tasks/upgrade.rake
@@ -1,3 +1,4 @@
+require 'set'
namespace :upgrade do
desc "Upgrade to 1.0"
@@ -274,5 +275,98 @@
end
end
+ desc "Remove duplicated non customised template versions"
+ task remove_duplicated_non_customised_template_versions: :environment do
+ templates = Template
+ .select(:id, :family_id, :version, :updated_at)
+ .group(:family_id, :version, :id)
+ .order(family_id: :asc, version: :asc, updated_at: :desc)
+ current_family_id = nil
+ unique_versions = Set.new
+ duplicates = []
+ templates.each do |template|
+ if current_family_id != template.family_id
+ current_family_id = template.family_id
+ unique_versions = Set.new
+ end
+ if unique_versions.add?(template.version).nil?
+ duplicates << template
+ end
+ end
+ current_family_id = nil
+ version_counter = nil
+ duplicates.each do |template|
+ if current_family_id != template.family_id
+ current_family_id = template.family_id
+ version_counter = nil
+ end
+ num_plans = Plan.where(template_id: template.id).count
+ if num_plans > 0
+ version_counter = version_counter.nil? ? -1 : version_counter - 1
+ unsaved_template = Template.find(template.id)
+ unsaved_template.version = version_counter
+ if Template.exists?(customization_of: template.family_id)
+ puts "template with id: #{template.id} has NOT been ARCHIVED since it had customised templates"
+ else
+ puts "template with id: #{template.id} has been ARCHIVED since it had plans associated but no customised templates"
+ unsaved_template.archived = true
+ end
+ unsaved_template.save!
+ else
+ Template.destroy(template.id)
+ puts "template with id: #{template.id} has been REMOVED since it had no plans associated"
+ end
+ end
+ puts "remove_duplicated_non_customised_template_versions DONE"
+ end
+ desc "Remove duplicated customised template versions"
+ task remove_duplicated_customised_template_versions: :environment do
+ templates = Template
+ .select(:id, :customization_of, :version, :org_id, :updated_at)
+ .where('customization_of IS NOT NULL')
+ .group(:customization_of, :org_id, :version, :id)
+ .order(customization_of: :asc, org_id: :asc, version: :asc, updated_at: :desc)
+ generate_compound_key = lambda{ |customization_of, org_id| return "#{customization_of}_#{org_id}" }
+ current = nil
+ unique_versions = Set.new
+ duplicates = []
+ templates.each do |template|
+ key = generate_compound_key.call(template.customization_of, template.org_id)
+ if current != key
+ current = key
+ unique_versions = Set.new
+ end
+ if unique_versions.add?(template.version).nil?
+ duplicates << template
+ end
+ end
+ current = nil
+ version_counter = nil
+ duplicates.each do |template|
+ key = generate_compound_key.call(template.customization_of, template.org_id)
+ if current != key
+ current = key
+ version_counter = nil
+ end
+ num_plans = Plan.where(template_id: template.id).count
+ if num_plans > 0
+ version_counter = version_counter.nil? ? -1 : version_counter - 1
+ unsaved_template = Template.find(template.id)
+ unsaved_template.version = version_counter
+ unsaved_template.archived = true
+ unsaved_template.save!
+ puts "template with id: #{template.id} has been ARCHIVED since it had plans associated"
+ else
+ Template.destroy(template.id)
+ puts "template with id: #{template.id} has been REMOVED since it has no plans associated"
+ end
+ end
+ puts "remove_duplicated_customised_template_versions DONE"
+ end
+ desc "Remove duplicated template versions"
+ task remove_duplicated_template_versions: :environment do
+ Rake::Task['upgrade:remove_duplicated_non_customised_template_versions'].execute
+ Rake::Task['upgrade:remove_duplicated_customised_template_versions'].execute
+ end
end
diff --git a/lib/template_filter.rb b/lib/template_filter.rb
deleted file mode 100644
index 44a5189..0000000
--- a/lib/template_filter.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-module TemplateFilter
- # Applies scoping to the template list
- def apply_scoping(scope, customizable = false, all = false)
- if customizable
- # Retrieve all of the publicly visible published funder templates
- orgs = Org.funder.where.not(id: current_user.org.id)
- # Include the default template in the list of funder templates
- orgs << Template.default.org unless current_user.org == Template.default.org
-
- templates = Template.get_public_published_template_versions(orgs)
-
- # If the user is an Org Admin look for customizations to funder templates
- customizations = {}
- if current_user.can_org_admin?
- families = templates.collect(&:dmptemplate_id).uniq
- Template.org_customizations(families, current_user.org_id).each do |customization|
- customizations[customization.customization_of] = customization if customization.present?
- end
- end
-
- scopes = calculate_table_scopes(templates, customizations)
-
- # We scope based on the customizations
- if params[:scope].present? && params[:scope] != 'all'
- scoped = templates.select do |t|
- c = customizations[t.dmptemplate_id]
- (params[:scope] == 'unpublished' && (!c.present? || !c.published?)) || (params[:scope] == 'published' && c.present? && c.published?)
- end
- templates = Template.where(id: scoped.collect(&:id))
- end
-
- else
- # If we're collecting all templates
- if all
- templates = Template.get_latest_template_versions(Org.all)
- else
- templates = Template.get_latest_template_versions(Org.where(id: current_user.org.id))
- end
-
- scopes = calculate_table_scopes(templates, {})
-
- if params[:scope].present? && params[:scope] != 'all'
- templates = templates.where(published: true) if params[:scope] == 'published'
- templates = templates.where(published: false) if params[:scope] == 'unpublished'
- end
- end
-
- { templates: templates,
- customizations: customizations || {},
- scopes: scopes }
- end
-
- private
- # Gets the nbr of templates and nbr of published/unpublished templates
- def calculate_table_scopes(templates, customizations)
- scopes = { all: templates.length, published: 0, unpublished: 0, dmptemplate_ids: templates.collect(&:dmptemplate_id).uniq }
- templates.each do |t|
- # If we have customizations use their status
- if customizations.keys.length > 0
- c = customizations[t.dmptemplate_id]
- # If the template was not customized then its unpublished
- if c.nil?
- scopes[:unpublished] += 1
- else
- scopes[:published] += 1 if c.published?
- scopes[:unpublished] += 1 unless c.published?
- end
- else
- # Otherwise just use the template's published status
- scopes[:published] += 1 if t.published?
- scopes[:unpublished] += 1 unless t.published?
- end
- end
- scopes
- end
-
- def get_publication_dates(family_ids)
- published = {}
- lives = Template.live(family_ids)
- lives.each do |live|
- published[live.dmptemplate_id] = live.updated_at
- end
- published
- end
-end
\ No newline at end of file
diff --git a/public/html/created.rid b/public/html/created.rid
index 1ff390d..7b8cddd 100644
--- a/public/html/created.rid
+++ b/public/html/created.rid
@@ -108,7 +108,6 @@
config/initializers/mime_types.rb Mon, 14 Jul 2014 15:43:22 +0100
config/initializers/omniauth.rb Mon, 07 Jul 2014 11:30:12 +0100
config/initializers/recaptcha.rb Wed, 16 Jul 2014 16:29:56 +0100
-config/initializers/rolify.rb Tue, 24 Sep 2013 15:31:14 +0100
config/initializers/secret_token.rb Mon, 14 Jul 2014 15:43:22 +0100
config/initializers/session_store.rb Tue, 24 Sep 2013 15:31:14 +0100
config/initializers/wrap_parameters.rb Tue, 24 Sep 2013 15:31:14 +0100
diff --git a/test/functional/annotations_controller_test.rb b/test/functional/annotations_controller_test.rb
deleted file mode 100644
index f8ea039..0000000
--- a/test/functional/annotations_controller_test.rb
+++ /dev/null
@@ -1,98 +0,0 @@
-require 'test_helper'
-
-class AnnotationsControllerTest < ActionDispatch::IntegrationTest
-
- include Devise::Test::IntegrationHelpers
-
- setup do
- @question = Annotation.first.question
-
- # Get the first Org Admin
- scaffold_org_admin(@question.section.phase.template.org)
-
- # clear the existing annotations
- @question.annotations.where(org: @user.org).each do |annotation|
- annotation.destroy!
- end
-
- @create_hash = {question_id: @question.id, example_answer_text: "New example", guidance_text: "New guidance"}
- @example_answer_qry = {question: @question, org: @user.org, type: Annotation.types[:example_answer]}
- @guidance_qry = {question: @question, org: @user.org, type: Annotation.types[:guidance]}
- end
-
- test "cannot create/update if not logged in" do
- # Should redirect user to the root path if they are not logged in!
- put admin_update_annotation_path(id: @question.section.phase.id), @create_hash
- assert_unauthorized_redirect_to_root_path
- end
-
- test "can create example answer and guidance at the same time" do
- sign_in @user
- put admin_update_annotation_path(id: @question.section.phase.id), @create_hash
- assert_response :redirect
- assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?section_id=#{@question.section.id}&r=all-templates"
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('example answer') && flash[:notice].include?('guidance')
- assert_equal 'New example', Annotation.find_by(@example_answer_qry).text, "expected example answer to have been created."
- assert_equal 'New guidance', Annotation.find_by(@guidance_qry).text, "expected guidance to have been created."
- end
- test "can create example answer without a guidance" do
- sign_in @user
- put admin_update_annotation_path(id: @question.section.phase.id), {question_id: @question.id, example_answer_text: "New example"}
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('updated')
- assert_response :redirect
- assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?section_id=#{@question.section.id}&r=all-templates"
- assert_equal 'New example', Annotation.find_by(@example_answer_qry).text, "expected example answer to have been created."
- assert Annotation.find_by(@guidance_qry).nil?, "expected no guidance to have been created."
- end
- test "can create guidance without an example answer" do
- sign_in @user
- put admin_update_annotation_path(id: @question.section.phase.id), {question_id: @question.id, guidance_text: "New guidance"}
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('updated')
- assert_response :redirect
- assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?section_id=#{@question.section.id}&r=all-templates"
- assert Annotation.find_by(@example_answer_qry).nil?, "expected no example answer to have been created."
- assert_equal 'New guidance', Annotation.find_by(@guidance_qry).text, "expected guidance to have been created."
- end
-
- test "can update example answer and guidance at the same time" do
- put admin_update_annotation_path(id: @question.section.phase.id), @create_hash
- sign_in @user
- put admin_update_annotation_path(id: @question.section.phase.id), {question_id: @question.id, example_answer_text: "Updated example", guidance_text: "Updated guidance"}
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('updated')
- assert_response :redirect
- assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?section_id=#{@question.section.id}&r=all-templates"
- assert_equal 'Updated example', Annotation.find_by(@example_answer_qry).text, "expected example answer to have been updated."
- assert_equal 'Updated guidance', Annotation.find_by(@guidance_qry).text, "expected guidance to have been updated."
- end
- test "can remove example answer by not submitting it during save" do
- put admin_update_annotation_path(id: @question.section.phase.id), @create_hash
- sign_in @user
- put admin_update_annotation_path(id: @question.section.phase.id), {question_id: @question.id, guidance_text: "Updated guidance"}
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('updated')
- assert_response :redirect
- assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?section_id=#{@question.section.id}&r=all-templates"
- assert Annotation.find_by(@example_answer_qry).nil?, "expected example answer to have been removed."
- assert_equal 'Updated guidance', Annotation.find_by(@guidance_qry).text, "expected guidance to have been updated."
- end
- test "can remove guidance by not submitting it during save" do
- put admin_update_annotation_path(id: @question.section.phase.id), @create_hash
- sign_in @user
- put admin_update_annotation_path(id: @question.section.phase.id), {question_id: @question.id, example_answer_text: "Updated example"}
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('updated')
- assert_response :redirect
- assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?section_id=#{@question.section.id}&r=all-templates"
- assert_equal 'Updated example', Annotation.find_by(@example_answer_qry).text, "expected example answer to have been updated."
- assert Annotation.find_by(@guidance_qry).nil?, "expected guidance to have been removed."
- end
-
- test "can delete a specific annotation" do
- sign_in @user
- put admin_update_annotation_path(id: @question.section.phase.id), @create_hash
- delete admin_destroy_annotation_path(Annotation.find_by(@example_answer_qry))
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('deleted')
- assert_response :redirect
- assert_redirected_to "#{admin_show_phase_path(@question.section.phase.id)}?section_id=#{@question.section.id}&r=all-templates"
- assert Annotation.find_by(@example_answer_qry).nil?
- assert_equal 'New guidance', Annotation.find_by(@guidance_qry).text, "expected guidance to have been unchanged."
- end
-end
\ No newline at end of file
diff --git a/test/functional/notifications_controller_test.rb b/test/functional/notifications_controller_test.rb
new file mode 100644
index 0000000..8616c5d
--- /dev/null
+++ b/test/functional/notifications_controller_test.rb
@@ -0,0 +1,83 @@
+require 'test_helper'
+module SuperAdmin
+ class NotificationsControllerTest < ActionController::TestCase
+ include Devise::Test::ControllerHelpers
+
+ setup do
+ @super_admin = User.find_by(email: 'super_admin@example.com')
+ scaffold_org_admin(Org.last)
+
+ @notification_attributes = {
+ notification_type: Notification.notification_types[:global],
+ title: 'notification_1',
+ level: Notification.levels[:info],
+ body: 'notification 1',
+ dismissable: true,
+ starts_at: Date.today,
+ expires_at: Date.tomorrow
+ }
+ @notification = Notification.create!(@notification_attributes)
+ end
+
+ test 'should get index' do
+ sign_in @super_admin
+ get :index
+ assert_response :success
+ assert_not_nil assigns(:notifications)
+ end
+
+ test 'should get new' do
+ sign_in @super_admin
+ get :new
+ assert_response :success
+ end
+
+ test 'should create notification' do
+ sign_in @super_admin
+ assert_difference('Notification.count') do
+ @notification_attributes[:level] = :info #controller is expecting the symbol instead of the numerical value
+ post :create, notification: @notification_attributes
+ end
+ assert_redirected_to super_admin_notifications_url
+ end
+
+ test 'should get edit' do
+ sign_in @super_admin
+ get :edit, id: @notification
+ assert_response :success
+ assert_not_nil assigns(:notification)
+ end
+
+ test 'should update notification' do
+ sign_in @super_admin
+ @notification_attributes[:title] = 'notification_2'
+ @notification_attributes[:level] = :info #controller is expecting the symbol instead of the numerical value
+ patch :update, id: @notification, notification: @notification_attributes
+ assert_redirected_to super_admin_notifications_url
+ end
+
+ test 'should destroy notification' do
+ sign_in @super_admin
+ assert_difference('Notification.count', -1) do
+ delete :destroy, id: @notification
+ end
+ assert_redirected_to super_admin_notifications_url
+ end
+
+ test 'unauthorized redirections' do
+ sign_in @user
+ get :index
+ assert_redirected_to(plans_url)
+ get :new
+ assert_redirected_to(plans_url)
+ post :create, notification: @notification_attributes
+ assert_redirected_to(plans_url)
+ get :edit, id: @notification
+ assert_redirected_to(plans_url)
+ patch :update, id: @notification, notification: @notification_attributes
+ assert_redirected_to(plans_url)
+ delete :destroy, id: @notification
+ assert_redirected_to(plans_url)
+ end
+ end
+end
diff --git a/test/functional/org_admin/phases_controller_test.rb b/test/functional/org_admin/phases_controller_test.rb
new file mode 100644
index 0000000..b7d4263
--- /dev/null
+++ b/test/functional/org_admin/phases_controller_test.rb
@@ -0,0 +1,146 @@
+require 'test_helper'
+
+class PhasesControllerTest < ActionDispatch::IntegrationTest
+
+ include Devise::Test::IntegrationHelpers
+
+ setup do
+ @institution = init_institution
+ @researcher = init_researcher(@institution)
+ @org_admin = init_org_admin(@institution)
+ @template = init_template(@institution, {
+ title: 'Test Template',
+ published: true,
+ visibility: Template.visibilities[:publicly_visible]
+ })
+ @phase = init_phase(@template)
+ end
+
+ test "unauthorized user cannot access the show/edit page" do
+ get org_admin_template_phase_path(@template, @phase)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ get org_admin_template_phase_path(@template, @phase)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can access the show/edit page' do
+ sign_in @org_admin
+ get org_admin_template_phase_path(@template, @phase)
+ assert_response :success
+ assert_nil flash[:notice]
+ assert_nil flash[:alert]
+ end
+
+ test "unauthorized user cannot access the preview phase page" do
+ get preview_org_admin_template_phase_path(@template, @phase)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ get preview_org_admin_template_phase_path(@template, @phase)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can access the preview phase page' do
+ sign_in @org_admin
+ get preview_org_admin_template_phase_path(@template, @phase)
+ assert_response :success
+ assert_nil flash[:notice]
+ assert_nil flash[:alert]
+ end
+
+ test "unauthorized user cannot access the new phase page" do
+ get new_org_admin_template_phase_path(@template)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ get new_org_admin_template_phase_path(@template)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can access the new phase page' do
+ sign_in @org_admin
+ get new_org_admin_template_phase_path(@template)
+ assert_response :success
+ assert_nil flash[:notice]
+ assert_nil flash[:alert]
+ end
+
+ test 'unauthorized user cannot create a phase' do
+ params = { phase: { title: 'New phase', number: 2 } }
+ post org_admin_template_phases_path(@template), params
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ post org_admin_template_phases_path(@template), params
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can create a phase for an unpublished template' do
+ @template.update!(published: false)
+ params = { phase: { title: 'New phase', number: 2 } }
+ sign_in @org_admin
+ post org_admin_template_phases_path(@template), params
+ assert_response :redirect
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: @template.id, id: @template.phases.last.id)
+ end
+
+ test 'authorized user can create a phase for a published template' do
+ params = { phase: { title: 'New phase', number: 2 } }
+ sign_in @org_admin
+ post org_admin_template_phases_path(@template), params
+ assert_response :redirect
+ template = Template.latest_version(@template.family_id).first
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: template.id, id: template.phases.last.id)
+ end
+
+ test 'unauthorized user cannot edit a phase' do
+ params = { phase: { title: 'New phase' } }
+ put org_admin_template_phase_path(@template, @phase), params
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ put org_admin_template_phase_path(@template, @phase), params
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can edit a phase for an unpublished template' do
+ @template.update!(published: false)
+ params = { phase: { title: 'New phase' } }
+ sign_in @org_admin
+ put org_admin_template_phase_path(@template, @phase), params
+ assert_response :redirect
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: @template.id, id: @template.phases.last.id)
+ end
+
+ test 'authorized user can edit a phase for a published template' do
+ params = { phase: { title: 'New phase' } }
+ sign_in @org_admin
+ put org_admin_template_phase_path(@template, @phase), params
+ assert_response :redirect
+ template = Template.latest_version(@template.family_id).first
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: template.id, id: template.phases.last.id)
+ end
+
+ test 'unauthorized user cannot delete a phase' do
+ delete org_admin_template_phase_path(@template, @phase)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ delete org_admin_template_phase_path(@template, @phase)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can delete a phase from an unpublished template' do
+ @template.update!(published: false)
+ params = { phase: { title: 'New phase' } }
+ sign_in @org_admin
+ delete org_admin_template_phase_path(@template, @phase)
+ assert_response :redirect
+ assert_redirected_to edit_org_admin_template_path(@template.id)
+ end
+
+ test 'authorized user can delete a phase from a published template' do
+ params = { phase: { title: 'New phase' } }
+ sign_in @org_admin
+ delete org_admin_template_phase_path(@template, @phase)
+ assert_response :redirect
+ template = Template.latest_version(@template.family_id).first
+ assert_redirected_to edit_org_admin_template_path(template.id)
+ end
+end
diff --git a/test/functional/org_admin/questions_controller_test.rb b/test/functional/org_admin/questions_controller_test.rb
new file mode 100644
index 0000000..1324e3f
--- /dev/null
+++ b/test/functional/org_admin/questions_controller_test.rb
@@ -0,0 +1,133 @@
+require 'test_helper'
+
+class QuestionsControllerTest < ActionDispatch::IntegrationTest
+
+ include Devise::Test::IntegrationHelpers
+
+ setup do
+ @institution = init_institution
+ @researcher = init_researcher(@institution)
+ @org_admin = init_org_admin(@institution)
+ @template = init_template(@institution, {
+ title: 'Test Template',
+ published: true,
+ visibility: Template.visibilities[:publicly_visible]
+ })
+ @phase = init_phase(@template)
+ @section = init_section(@phase)
+ @text_area = init_question_format({ title: 'Test question format' })
+ @question = init_question(@section)
+ end
+
+ test 'unauthorized user cannot call question_controller#create' do
+ params = { question: { text: 'New question test', number: 2, question_format_id: @text_area.id } }
+ post org_admin_template_phase_section_questions_path(@template, @phase, @section), params
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ post org_admin_template_phase_section_questions_path(@template, @phase, @section), params
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'unauthorized user cannot call question_controller#create for another org\'s template' do
+ params = { question: { text: 'New question test', number: 2, question_format_id: @text_area.id } }
+ funder = init_funder
+ funder_template = init_template(funder)
+ funder_phase = init_phase(funder_template)
+ funder_section = init_section(funder_phase)
+ sign_in @org_admin
+ post org_admin_template_phase_section_questions_path(funder_template, funder_phase, funder_section), params
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can call question_controller#create for an unpublished template' do
+ @template.update!(published: false)
+ params = { question: { text: 'New question test', number: 2, question_format_id: @text_area.id } }
+ sign_in @org_admin
+ post org_admin_template_phase_section_questions_path(@template, @phase, @section), params
+ assert_response :redirect
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: @template.id, id: @phase.id, section: @section.id)
+ end
+
+ test 'authorized user can call question_controller#create for a published template' do
+ params = { question: { text: 'New question test', number: 2, question_format_id: @text_area.id } }
+ sign_in @org_admin
+ post org_admin_template_phase_section_questions_path(@template, @phase, @section), params
+ assert_response :redirect
+ template = Template.latest_version(@template.family_id).first
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: template.id, id: template.phases.first.id, section: template.phases.first.sections.first.id)
+ end
+
+ test 'unauthorized user cannot call question_controller#edit' do
+ params = { section: { text: 'Edited question' } }
+ put org_admin_template_phase_section_question_path(@template, @phase, @section, @question), params
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ put org_admin_template_phase_section_question_path(@template, @phase, @section, @question), params
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'unauthorized user cannot call question_controller#edit for another org\'s template' do
+ params = { section: { text: 'Edited question' } }
+ funder = init_funder
+ funder_template = init_template(funder)
+ funder_phase = init_phase(funder_template)
+ funder_section = init_section(funder_phase)
+ funder_question = init_question(funder_section)
+ sign_in @org_admin
+ put org_admin_template_phase_section_question_path(funder_template, funder_phase, funder_section, funder_question), params
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can call question_controller#edit for an unpublished template' do
+ @template.update!(published: false)
+ params = { section: { text: 'Edited question' } }
+ sign_in @org_admin
+ put org_admin_template_phase_section_question_path(@template, @phase, @section, @question), params
+ assert_response :redirect
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: @template.id, id: @phase.id, section: @section.id)
+ end
+
+ test 'authorized user can call question_controller#edit for a published template' do
+ params = { section: { text: 'Edited question' } }
+ sign_in @org_admin
+ put org_admin_template_phase_section_question_path(@template, @phase, @section, @question), params
+ assert_response :redirect
+ template = Template.latest_version(@template.family_id).first
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: template.id, id: template.phases.first.id, section: template.phases.first.sections.first.id)
+ end
+
+ test 'unauthorized user cannot call question_controller#destroy' do
+ delete org_admin_template_phase_section_question_path(@template, @phase, @section, @question)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ delete org_admin_template_phase_section_question_path(@template, @phase, @section, @question)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'unauthorized user cannot call question_controller#destroy for another org\'s template' do
+ funder = init_funder
+ funder_template = init_template(funder)
+ funder_phase = init_phase(funder_template)
+ funder_section = init_section(funder_phase)
+ funder_question = init_question(funder_section)
+ sign_in @org_admin
+ delete org_admin_template_phase_section_question_path(funder_template, funder_phase, funder_section, funder_question)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can call question_controller#destroy for an unpublished template' do
+ @template.update!(published: false)
+ sign_in @org_admin
+ delete org_admin_template_phase_section_question_path(@template, @phase, @section, @question)
+ assert_response :redirect
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: @template.id, id: @phase.id, section: @section.id)
+ end
+
+ test 'authorized user can call question_controller#destroy for a published template' do
+ sign_in @org_admin
+ delete org_admin_template_phase_section_question_path(@template, @phase, @section, @question)
+ assert_response :redirect
+ template = Template.latest_version(@template.family_id).first
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: template.id, id: template.phases.first.id, section: template.phases.first.sections.first.id)
+ end
+end
\ No newline at end of file
diff --git a/test/functional/org_admin/sections_controller_test.rb b/test/functional/org_admin/sections_controller_test.rb
new file mode 100644
index 0000000..6bb2c4c
--- /dev/null
+++ b/test/functional/org_admin/sections_controller_test.rb
@@ -0,0 +1,174 @@
+require 'test_helper'
+
+class SectionsControllerTest < ActionDispatch::IntegrationTest
+
+ include Devise::Test::IntegrationHelpers
+
+ setup do
+ @institution = init_institution
+ @researcher = init_researcher(@institution)
+ @org_admin = init_org_admin(@institution)
+ @template = init_template(@institution, {
+ title: 'Test Template',
+ published: true,
+ visibility: Template.visibilities[:publicly_visible]
+ })
+ @phase = init_phase(@template)
+ @section = init_section(@phase)
+ end
+
+ test "unauthorized user cannot access the index page" do
+ get org_admin_template_phase_sections_path(@template, @phase)
+ assert_unauthorized_redirect_to_root_path
+ end
+
+ test 'authorized user can access the index page' do
+ [@researcher, @org_admin].each do |user|
+ sign_in user
+ get org_admin_template_phase_sections_path(@template, @phase)
+ assert_response :success, "expected #{user.name(false)} to be able to access the section_controller#index page"
+ assert_nil flash[:notice]
+ assert_nil flash[:alert]
+ end
+ end
+
+ test "unauthorized user cannot access the section_controller#show page" do
+ get org_admin_template_phase_section_path(@template, @phase, @section)
+ assert_unauthorized_redirect_to_root_path
+ end
+
+ test 'authorized user can access the section_controller#show page' do
+ [@researcher, @org_admin].each do |user|
+ sign_in user
+ get org_admin_template_phase_section_path(@template, @phase, @section)
+ assert_response :success, "expected #{user.name(false)} to be able to access the section_controller#show page"
+ assert_nil flash[:notice]
+ assert_nil flash[:alert]
+ end
+ end
+
+ test "unauthorized user cannot access the section_controller#edit page" do
+ get edit_org_admin_template_phase_section_path(@template, @phase, @section)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ get edit_org_admin_template_phase_section_path(@template, @phase, @section)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can access the section_controller#edit page' do
+ sign_in @org_admin
+ get edit_org_admin_template_phase_section_path(@template, @phase, @section)
+ assert_response :success
+ assert_nil flash[:notice]
+ assert_nil flash[:alert]
+ end
+
+ test 'unauthorized user cannot call section_controller#create' do
+ params = { section: { title: 'New section', number: 2 } }
+ post org_admin_template_phase_sections_path(@template, @phase), params
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ post org_admin_template_phase_sections_path(@template, @phase), params
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'unauthorized user cannot call section_controller#create for another org\'s template' do
+ params = { section: { title: 'New section', number: 2 } }
+ funder = init_funder
+ funder_template = init_template(funder)
+ funder_phase = init_phase(funder_template)
+ sign_in @org_admin
+ post org_admin_template_phase_sections_path(funder_template, funder_phase), params
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can call section_controller#create for an unpublished template' do
+ @template.update!(published: false)
+ params = { section: { title: 'New section', number: 2 } }
+ sign_in @org_admin
+ post org_admin_template_phase_sections_path(@template, @phase), params
+ assert_response :redirect
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: @template.id, id: @phase.id, section: @phase.sections.last.id)
+ end
+
+ test 'authorized user can call section_controller#create for a published template' do
+ params = { section: { title: 'New section', number: 2 } }
+ sign_in @org_admin
+ post org_admin_template_phase_sections_path(@template, @phase), params
+ assert_response :redirect
+ template = Template.latest_version(@template.family_id).first
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: template.id, id: template.phases.first.id, section: template.phases.first.sections.last.id)
+ end
+
+ test 'unauthorized user cannot call section_controller#edit' do
+ params = { section: { title: 'Edited section' } }
+ put org_admin_template_phase_section_path(@template, @phase, @section), params
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ put org_admin_template_phase_section_path(@template, @phase, @section), params
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'unauthorized user cannot call section_controller#edit for another org\'s template' do
+ params = { section: { title: 'Edited section' } }
+ funder = init_funder
+ funder_template = init_template(funder)
+ funder_phase = init_phase(funder_template)
+ funder_section = init_section(funder_phase)
+ sign_in @org_admin
+ put org_admin_template_phase_section_path(funder_template, funder_phase, funder_section), params
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can call section_controller#edit for an unpublished template' do
+ @template.update!(published: false)
+ params = { section: { title: 'Edited section' } }
+ sign_in @org_admin
+ put org_admin_template_phase_section_path(@template, @phase, @section), params
+ assert_response :redirect
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: @template.id, id: @phase.id, section: @phase.sections.last.id)
+ end
+
+ test 'authorized user can call section_controller#edit for a published template' do
+ params = { section: { title: 'Edited section' } }
+ sign_in @org_admin
+ put org_admin_template_phase_section_path(@template, @phase, @section), params
+ assert_response :redirect
+ template = Template.latest_version(@template.family_id).first
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: template.id, id: template.phases.first.id, section: template.phases.first.sections.last.id)
+ end
+
+ test 'unauthorized user cannot call section_controller#destroy' do
+ delete org_admin_template_phase_section_path(@template, @phase, @section)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ delete org_admin_template_phase_section_path(@template, @phase, @section)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'unauthorized user cannot call section_controller#destroy for another org\'s template' do
+ funder = init_funder
+ funder_template = init_template(funder)
+ funder_phase = init_phase(funder_template)
+ funder_section = init_section(funder_phase)
+ sign_in @org_admin
+ delete org_admin_template_phase_section_path(funder_template, funder_phase, funder_section)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test 'authorized user can call section_controller#destroy for an unpublished template' do
+ @template.update!(published: false)
+ sign_in @org_admin
+ delete org_admin_template_phase_section_path(@template, @phase, @section)
+ assert_response :redirect
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: @template.id, id: @phase.id)
+ end
+
+ test 'authorized user can call section_controller#destroy for a published template' do
+ sign_in @org_admin
+ delete org_admin_template_phase_section_path(@template, @phase, @section)
+ assert_response :redirect
+ template = Template.latest_version(@template.family_id).first
+ assert_redirected_to edit_org_admin_template_phase_path(template_id: template.id, id: template.phases.first.id)
+ end
+end
\ No newline at end of file
diff --git a/test/functional/org_admin/templates_controller_test.rb b/test/functional/org_admin/templates_controller_test.rb
index 569cfb0..d09ff86 100644
--- a/test/functional/org_admin/templates_controller_test.rb
+++ b/test/functional/org_admin/templates_controller_test.rb
@@ -5,567 +5,305 @@
include Devise::Test::IntegrationHelpers
setup do
- scaffold_template
-
- # Get the first Org Admin
- scaffold_org_admin(@template.org)
+ @funder = init_funder
+ @institution = init_institution
+ @organisation = init_organisation
- @regular_user = User.find_by(email: 'org_user@example.com')
+ @researcher = init_researcher(@institution)
+ @org_admin = init_org_admin(@institution)
+ @super_admin = init_super_admin(@organisation)
+
+ @funder_template = init_template(@funder, {
+ title: 'Test Funder Template',
+ published: true,
+ visibility: Template.visibilities[:publicly_visible]
+ })
+ @org_template = init_template(@institution, {
+ title: 'Test Org Template',
+ published: true
+ })
end
- test "unauthorized user cannot access the templates page" do
- # Should redirect user to the root path if they are not logged in!
+ test "unauthorized user cannot access the templates#index page" do
get org_admin_templates_path
assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
+ sign_in @researcher
+ get org_admin_templates_path
+ assert_authorized_redirect_to_plans_page
+ sign_in @org_admin
get org_admin_templates_path
assert_authorized_redirect_to_plans_page
end
- test "Org admin sees the correct templates on the templates page" do
- init_templates
- sign_in @org_admin
- get org_admin_templates_path
-
- verify_all_templates_table(@org_admin)
- verify_own_templates_table(@org_admin)
- verify_funder_templates_table(@org_admin)
- end
-
- test "Funder admin sees the correct templates on the templates page" do
- init_templates
- sign_in @funder_admin
- get org_admin_templates_path
-
- verify_all_templates_table(@funder_admin)
- verify_own_templates_table(@funder_admin)
- verify_funder_templates_table(@funder_admin)
- end
-
- test "Super admin sees the correct templates on the templates page" do
- init_templates
+ test "authorized user can access the templates#index page" do
sign_in @super_admin
get org_admin_templates_path
-
- verify_all_templates_table(@super_admin)
- verify_own_templates_table(@super_admin)
- verify_funder_templates_table(@super_admin)
- end
-
- test "Predefined scopes correctly filter results on all templates table" do
- init_templates
- sign_in @super_admin
- get org_admin_templates_path
-
- verify_all_templates_table(@super_admin)
-
- published = Template.latest_version.where(published: true, customization_of: nil)
- unpublished = Template.latest_version.where(published: false, customization_of: nil)
- verify_templates_table_scoping(all_paginable_templates_path('ALL'), '#all-templates', published, unpublished)
- end
-
- test "Predefined scopes correctly filter results on own templates table" do
- init_templates
- sign_in @org_admin
- get org_admin_templates_path
-
- verify_all_templates_table(@org_admin)
-
- published = Template.get_latest_template_versions(@org_admin.org).where(published: true, customization_of: nil)
- unpublished = Template.get_latest_template_versions(@org_admin.org).where(published: false, customization_of: nil)
- verify_templates_table_scoping(orgs_paginable_templates_path('ALL'), '#organisation-templates', published, unpublished)
- end
-
- test "Predefined scopes correctly filter results on customizable templates table" do
- init_templates
- sign_in @org_admin
- get org_admin_templates_path
-
- verify_all_templates_table(@org_admin)
-
- published = Template.where(title: 'UOS customization of Default template')
- unpublished = Template.where('published = 1 AND visibility = 1 AND is_default = 0')
- verify_templates_table_scoping(funders_paginable_templates_path('ALL'), '#funders-templates', published, unpublished)
- end
-
- test "unauthorized user cannot access the template edit page" do
- # Should redirect user to the root path if they are not logged in!
- get edit_org_admin_template_path(@template)
- assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
- get edit_org_admin_template_path(@template)
- assert_authorized_redirect_to_plans_page
- end
-
- test 'get templates#edit returns ok when template is current and is NOT published' do
- sign_in @user
- get(edit_org_admin_template_path(@template.id))
- assert_response(:ok)
- assert_nil(flash[:notice])
- end
-
- test 'get templates#edit returns ok with flash notice when template is not current' do
- new_version = Template.deep_copy(@template)
- new_version.version = (@template.version + 1)
- new_version.save
- sign_in @user
- get(edit_org_admin_template_path(@template.id))
- assert_response(:ok)
- assert_equal(_('You are viewing a historical version of this template. You will not be able to make changes.'), flash[:notice])
- end
-
- test "unauthorized user cannot access the new template page" do
- # Should redirect user to the root path if they are not logged in!
- get new_org_admin_template_path(Template.last.id)
- assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
- get new_org_admin_template_path(Template.last.id)
- assert_authorized_redirect_to_plans_page
- end
-
- test "get the new template page" do
- sign_in @user
-
- get new_org_admin_template_path(Template.last.id)
assert_response :success
end
- test "unauthorized user cannot access the template history page" do
- # Should redirect user to the root path if they are not logged in!
- get history_org_admin_template_path(@template)
+ test "unauthorized user cannot access the templates#organisational page" do
+ get organisational_org_admin_templates_path
assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
- get history_org_admin_template_path(@template)
+ sign_in @researcher
+ get organisational_org_admin_templates_path
assert_authorized_redirect_to_plans_page
end
-
- test "get the template history page" do
- sign_in @user
- get history_org_admin_template_path(@template)
+ test "authorized user can access the templates#organisational page" do
+ sign_in @org_admin
+ get organisational_org_admin_templates_path
assert_response :success
-
- assert assigns(:template)
- assert assigns(:templates)
- assert assigns(:current)
end
-
- test "unauthorized user cannot delete a template" do
- # Should redirect user to the root path if they are not logged in!
- delete org_admin_template_path(@template)
+
+ test "unauthorized user cannot access the templates#customisable page" do
+ get customisable_org_admin_templates_path
assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
- delete org_admin_template_path(@template)
+ sign_in @researcher
+ get customisable_org_admin_templates_path
assert_authorized_redirect_to_plans_page
end
- test "delete the admin template" do
- id = @template.id
- sign_in @user
+ test "authorized user can access the templates#customisable page" do
+ sign_in @org_admin
+ get customisable_org_admin_templates_path
+ assert_response :success
+ end
+
+ test "unauthorized user cannot access the template#edit page" do
+ get edit_org_admin_template_path(@org_template)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ get edit_org_admin_template_path(@org_template)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test "authorized user can access the template#edit page" do
+ sign_in @org_admin
+ get edit_org_admin_template_path(@org_template)
+ assert_response :success
+ end
- family = @template.dmptemplate_id
- prior = Template.current(family)
-
- version_the_template
-
- current = Template.current(family)
-
- # Try to delete a historical version should fail
- delete org_admin_template_path(prior)
- assert_equal _('You cannot delete historical versions of this template.'), flash[:alert]
- assert_response :redirect
- assert_redirected_to org_admin_templates_path(r: 'all-templates')
- assert_not Template.find(prior.id).nil?
-
- # Try to delete the current version should work
- delete org_admin_template_path(current)
- assert_response :redirect
- assert_redirected_to org_admin_templates_path(r: 'all-templates')
- assert_raise ActiveRecord::RecordNotFound do
- Template.find(current.id).nil?
+ test "admin cannot access another org's template#edit page" do
+ sign_in @org_admin
+ get edit_org_admin_template_path(@funder_template)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test "super admin can access any org's template#edit page" do
+ sign_in @super_admin
+ [@org_template, @funder_template].each do |template|
+ get edit_org_admin_template_path(template)
+ assert_response :success
end
- assert_equal prior, Template.current(family), "expected the old version to now be the current version"
-
- # Should not be able to delete a template that has plans!
end
- test "unauthorized user cannot create a template" do
- # Should redirect user to the root path if they are not logged in!
- post org_admin_templates_path(@user.org), {template: {title: ''}}
+ test 'get templates#edit returns ok when template is latest' do
+ sign_in @org_admin
+ get(edit_org_admin_template_path(@org_template))
+ assert_response :success
+ assert_nil flash[:notice], 'expected no warning messages'
+ end
+
+ test 'get templates#edit returns ok with flash notice when template is not latest' do
+ new_version = @org_template.generate_version!
+ sign_in @org_admin
+ get(edit_org_admin_template_path(@org_template.id))
+ assert_response :success
+ assert_not_nil flash[:notice], 'expected a warning message'
+ end
+
+ test "unauthorized user cannot access the template#new page" do
+ get new_org_admin_template_path
assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
- post org_admin_templates_path(@user.org), {template: {title: ''}}
+ sign_in @researcher
+ get new_org_admin_template_path
assert_authorized_redirect_to_plans_page
end
- test "create a template" do
- params = {title: 'Testing create route'}
- sign_in @user
+ test "authorized user can access the template#new page" do
+ sign_in @org_admin
+ get new_org_admin_template_path
+ assert_response :success
+ end
+
+ test "unauthorized user cannot access the template#history page" do
+ get history_org_admin_template_path(@org_template)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ get history_org_admin_template_path(@org_template)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test "authorized user can access the template#history page" do
+ sign_in @org_admin
+ get history_org_admin_template_path(@org_template)
+ assert_response :success
+ end
- post org_admin_templates_path(@user.org), {template: params}
+ test "unauthorized user cannot access template#delete" do
+ delete org_admin_template_path(@org_template)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ delete org_admin_template_path(@org_template)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test "authorized user can access template#delete" do
+ sign_in @org_admin
+ delete org_admin_template_path(@org_template)
+ assert_response :redirect
+ assert_redirected_to org_admin_templates_path
+ assert_nil flash[:alert]
+ end
+
+ test "unauthorized user cannot create a template#create" do
+ post org_admin_templates_path(@institution), {template: {title: ''}}
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ post org_admin_templates_path(@institution), {template: {title: ''}}
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test "authorized user can create a template#create" do
+ params = {title: 'Testing create route'}
+ sign_in @org_admin
+
+ post org_admin_templates_path(@institution), {template: params}
assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('created')
assert_response :redirect
assert_redirected_to edit_org_admin_template_url(Template.last.id)
- assert assigns(:template)
- assert_equal 'Testing create route', Template.last.title, "expected the record to have been created!"
-
- # Invalid object
- post org_admin_templates_path(@user.org), {template: {title: nil, org_id: @user.org.id}}
- assert flash[:alert].starts_with?(_('Could not create your'))
- assert_response :success
- assert assigns(:template)
- assert assigns(:hash)
end
- test "unauthorized user cannot update a template" do
- # Should redirect user to the root path if they are not logged in!
- put org_admin_template_path(@template), {template: {title: ''}}
+ test "unauthorized user cannot update a template#update" do
+ put org_admin_template_path(@org_template), {template: {title: ''}}
assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
- put org_admin_template_path(@template), {template: {title: ''}}
+ sign_in @researcher
+ put org_admin_template_path(@org_template), {template: {title: ''}}
assert_authorized_redirect_to_plans_page
end
- test "update the template" do
+ test "authorized user can update the template#update" do
params = {title: 'ABCD'}
- sign_in @user
-
- family = @template.dmptemplate_id
- prior = Template.current(family)
-
- version_the_template
-
- current = Template.current(family)
-
- # We shouldn't be able to edit a historical version
- put org_admin_template_path(prior), {template: params}
- assert_response :forbidden
- json_body = ActiveSupport::JSON.decode(response.body)
- assert_equal(_('You can not edit a historical version of this template.'), json_body["msg"])
-
- # Make sure we get the right response when editing an unpublished template
- put org_admin_template_path(current), {template: params}
+ sign_in @org_admin
+ put org_admin_template_path(@org_template), {template: params}
assert_response :ok
json_body = ActiveSupport::JSON.decode(response.body)
assert json_body["msg"].start_with?('Successfully') && json_body["msg"].include?('saved')
- assert_equal('ABCD', current.reload.title, "expected the record to have been updated")
-
- # Make sure we get the right response when providing an invalid template
- put org_admin_template_path(current), {template: {title: nil}}
- assert_response :bad_request
- json_body = ActiveSupport::JSON.decode(response.body)
- assert json_body["msg"].starts_with?(_('Could not update your'))
end
- test "unauthorized user cannot customize a template" do
- # Make sure we are redirected if we're not logged in
- get customize_org_admin_template_path(@template)
+ test "unauthorized user cannot customize a template#customize" do
+ post customize_org_admin_template_path(@org_template)
assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
- get customize_org_admin_template_path(@template)
+ sign_in @researcher
+ post customize_org_admin_template_path(@org_template)
+ assert_authorized_redirect_to_plans_page
+ end
+
+ test "authorized user can customize a funder template#customize" do
+ @funder_template.update!({ published: true })
+ sign_in @org_admin
+ post customize_org_admin_template_path(@funder_template)
+ assert_response :redirect
+ assert_redirected_to org_admin_template_url(Template.latest_customized_version(@funder_template.family_id, @institution.id).first)
+ end
+
+ test "unauthorized user cannot publish a template#publish" do
+ patch publish_org_admin_template_path(@org_template)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ patch publish_org_admin_template_path(@org_template)
assert_authorized_redirect_to_plans_page
end
- test "customize a funder template" do
- funder_template = Template.create(org: Org.funder.first, title: 'Testing integration')
-
- # Sign in as the funder so that we cna publish the template
- sign_in User.find_by(org: funder_template.org)
-
- get publish_org_admin_template_path(funder_template)
- assert_response :redirect
- assert_redirected_to "#{org_admin_templates_path}#organisation-templates"
-
- # Sign in as the regular user so we can customize the funder template
- sign_in @user
-
- template = Template.live(funder_template.dmptemplate_id)
-
- get customize_org_admin_template_path(template)
-
- customization = Template.where(customization_of: template.dmptemplate_id).last
-
- assert_response :redirect
- assert_redirected_to edit_org_admin_template_url(Template.last, r: 'funder-templates')
- assert assigns(:template)
-
- assert_equal 0, customization.version
- assert_not customization.published?
- assert customization.dirty?
-
- # Make sure the funder templates data is not modifiable!
- customization.phases.each do |p|
- assert_not p.modifiable
- p.sections.each do |s|
- assert_not s.modifiable
- s.questions.each do |q|
- assert_not q.modifiable
- end
- end
- end
- end
-
- test "unauthorized user cannot publish a template" do
- # Should redirect user to the root path if they are not logged in!
- get publish_org_admin_template_path(@template)
- assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
- get publish_org_admin_template_path(@template)
+ test "authorized user cannot publish another org's template#publish" do
+ sign_in @org_admin
+ patch publish_org_admin_template_path(@funder_template)
assert_authorized_redirect_to_plans_page
end
- test "publish a template" do
- sign_in @user
-
- family = @template.dmptemplate_id
- prior = Template.current(family)
-
- version_the_template
-
- current = Template.current(family)
-
- # We shouldn't be able to edit a historical version
- get publish_org_admin_template_path(prior)
- assert_equal _('You can not publish a historical version of this template.'), flash[:alert]
- assert_response :redirect
- assert_redirected_to org_admin_templates_path
-
- # Publish the current template
- get publish_org_admin_template_path(current)
+ test "authorized user can publish a template#publish" do
+ sign_in @org_admin
+ patch publish_org_admin_template_path(@org_template)
assert_equal _('Your template has been published and is now available to users.'), flash[:notice]
assert_response :redirect
- assert_redirected_to "#{org_admin_templates_path}#organisation-templates"
- current = Template.current(family)
+ assert_redirected_to org_admin_templates_path
end
- test "unauthorized user cannot unpublish a template" do
- # Should redirect user to the root path if they are not logged in!
- get unpublish_org_admin_template_path(@template)
+ test "unauthorized user cannot unpublish a template#unpublish" do
+ patch unpublish_org_admin_template_path(@org_template)
assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
- get unpublish_org_admin_template_path(@template)
+ sign_in @researcher
+ patch unpublish_org_admin_template_path(@org_template)
assert_authorized_redirect_to_plans_page
end
- test "unpublish a template" do
- sign_in @user
-
- family = @template.dmptemplate_id
-
- prior = Template.current(family)
-
- version_the_template
-
- current = Template.current(family)
-
- # Publish it so we can unpublish
- get publish_org_admin_template_path(current)
- assert_not Template.live(family).nil?
-
- get unpublish_org_admin_template_path(current)
- assert_equal _('Your template is no longer published. Users will not be able to create new DMPs for this template until you re-publish it'), flash[:notice]
+ test "authorized user can unpublish a template#unpublish" do
+ sign_in @org_admin
+ patch unpublish_org_admin_template_path(@org_template)
assert_response :redirect
- assert_redirected_to "#{org_admin_templates_path}#organisation-templates"
-
- # Make sure there are no published versions
- assert Template.live(family).nil?
+ assert_redirected_to org_admin_templates_path
end
- test "unauthorized user cannot copy a template" do
- # Should redirect user to the root path if they are not logged in!
- get copy_org_admin_template_path(@template)
+ test "unauthorized user cannot copy a template#copy" do
+ post copy_org_admin_template_path(@org_template)
assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
- get copy_org_admin_template_path(@template)
+ sign_in @researcher
+ post copy_org_admin_template_path(@org_template)
assert_authorized_redirect_to_plans_page
end
- test "copy a template" do
- sign_in @user
- get copy_org_admin_template_path(@template)
+ test "unauthorized user cannot copy another org's template template#copy" do
+ sign_in @researcher
+ post copy_org_admin_template_path(@funder_template)
assert_response :redirect
- assert_redirected_to edit_org_admin_template_url(Template.last, edit: true, r: 'organisation-templates')
- end
-
- test "unauthorized user cannot transfer a template customization" do
- # Should redirect user to the root path if they are not logged in!
- get transfer_customization_org_admin_template_path(@template)
- assert_unauthorized_redirect_to_root_path
- # Non Org-Admin cannot perform this action
- sign_in @regular_user
- get transfer_customization_org_admin_template_path(@template)
assert_authorized_redirect_to_plans_page
end
- test "transfer a template customization" do
- # TODO add test for this. Could not get working, getting a nil for max_version within the method (NOT SURE IF THIS IS STILL IN USE!)
- end
-
- private
- def init_templates
- # First clear out any existing templates
- Template.all.each do |template|
- template.destroy!
- end
-
- @super_admin = User.find_by(email: 'super_admin@example.com')
- @org_admin = User.find_by(email: 'org_admin@example.com')
- @funder_admin = User.find_by(email: 'funder_admin@example.com')
-
- default_org = Org.find_by(org_type: 4)
- funder_org = Org.find_by(org_type: 2)
- institution_org = Org.find_by(org_type: 1)
- other_org = Org.create!(name: 'Another Org', abbreviation: 'BLAH', org_type: 3, links: {"org":[]})
-
- params = [{ title: 'Default template', org: default_org, migrated: false, dmptemplate_id: '00000100', published: true, version: 0, visibility: Template.visibilities[:publicly_visible], is_default: true },
- { title: 'UOS published A', org: institution_org, migrated: false, dmptemplate_id: '00000099', published: true, version: 0, visibility: Template.visibilities[:organisationally_visible], is_default: false },
- { title: 'UOS published B', org: institution_org, migrated: false, dmptemplate_id: '00000098', published: true, version: 0, visibility: Template.visibilities[:organisationally_visible], is_default: false },
- { title: 'UOS unpublished C', org: institution_org, migrated: false, dmptemplate_id: '00000097', published: false, version: 0, visibility: Template.visibilities[:organisationally_visible], is_default: false },
- { title: 'UOS unpublished Dv0', org: institution_org, migrated: false, dmptemplate_id: '00000096', published: false, version: 0, visibility: Template.visibilities[:organisationally_visible], is_default: false },
- { title: 'UOS published Dv1', org: institution_org, migrated: false, dmptemplate_id: '00000096', published: true, version: 1, visibility: Template.visibilities[:organisationally_visible], is_default: false },
- { title: 'UOS published Ev0', org: institution_org, migrated: false, dmptemplate_id: '00000095', published: true, version: 0, visibility: Template.visibilities[:organisationally_visible], is_default: false },
- { title: 'UOS unpublished Ev1', org: institution_org, migrated: false, dmptemplate_id: '00000095', published: false, version: 1, visibility: Template.visibilities[:organisationally_visible], is_default: false },
- { title: 'BLAH internal published A', org: other_org, migrated: false, dmptemplate_id: '00000079', published: true, version: 0, visibility: Template.visibilities[:organisationally_visible], is_default: false },
- { title: 'BLAH public published B', org: other_org, migrated: false, dmptemplate_id: '00000078', published: true, version: 0, visibility: Template.visibilities[:publicly_visible], is_default: false },
- { title: 'Funder public published A', org: funder_org, migrated: false, dmptemplate_id: '00000089', published: true, version: 0, visibility: Template.visibilities[:publicly_visible], is_default: false },
- { title: 'Funder internal published B', org: funder_org, migrated: false, dmptemplate_id: '00000088', published: true, version: 0, visibility: Template.visibilities[:organisationally_visible], is_default: false },
- { title: 'Funder internal unpublished B', org: funder_org, migrated: false, dmptemplate_id: '00000088', published: false, version: 1, visibility: Template.visibilities[:organisationally_visible], is_default: false },
- { title: 'Funder public unpublished C', org: funder_org, migrated: false, dmptemplate_id: '00000087', published: false, version: 0, visibility: Template.visibilities[:publicly_visible], is_default: false },
- { title: 'Funder public unpublished Dv0', org: funder_org, migrated: false, dmptemplate_id: '00000086', published: false, version: 0, visibility: Template.visibilities[:publicly_visible], is_default: false },
- { title: 'Funder public published Dv1', org: funder_org, migrated: false, dmptemplate_id: '00000086', published: true, version: 1, visibility: Template.visibilities[:publicly_visible], is_default: false },
- { title: 'Funder public published Ev0', org: funder_org, migrated: false, dmptemplate_id: '00000085', published: true, version: 0, visibility: Template.visibilities[:publicly_visible], is_default: false },
- { title: 'Funder public unpublished Ev1', org: funder_org, migrated: false, dmptemplate_id: '00000085', published: false, version: 1, visibility: Template.visibilities[:publicly_visible], is_default: false }]
-
- params.each do |hash|
- begin
- template = Template.new(hash)
- template.save!
- # Template's have default values when created, so override those defaults
- template.update_attributes!(published: hash[:published], visibility: hash[:visibility], is_default: hash[:is_default], dmptemplate_id: hash[:dmptemplate_id])
-
- if template.is_default?
- cust = Template.create!({ title: 'UOS customization of Default template', org: institution_org, migrated: false, version: 0})
- cust.update_attributes(published: true, customization_of: template.dmptemplate_id, visibility: Template.visibilities[:organisationally_visible])
- elsif template.title == 'Funder public published A'
- cust = Template.create!({ title: 'UOS customization of Funder public published A', org: institution_org, migrated: false, version: 0})
- cust.update_attributes(published: false, customization_of: template.dmptemplate_id, visibility: Template.visibilities[:organisationally_visible])
- end
- rescue ActiveRecord::RecordInvalid
- puts "EXCEPTION: #{template.errors.collect{ |e, m| "#{e}: #{m}" }.join(', ')}"
- end
- end
+ test "authorized super admin can copy another org's template template#copy" do
+ sign_in @super_admin
+ post copy_org_admin_template_path(@funder_template)
+ assert_response :redirect
+ assert_redirected_to edit_org_admin_template_url(Template.where(org_id: @organisation.id).order(id: :desc).last)
end
- def verify_all_templates_table(user)
- if user.can_super_admin?
- assert_select "#all-templates table tbody", true, "expected a super admin to be able to see the all templates table"
- else
- assert_select "#all-templates table tbody", false, "expected a non-super admin to NOT see the all templates table"
- end
+ test "authorized user can copy a template#copy" do
+ sign_in @org_admin
+ post copy_org_admin_template_path(@org_template)
+ assert_response :redirect
+ assert_redirected_to edit_org_admin_template_url(Template.where(org_id: @institution.id).last)
+ end
+
+ test "unauthorized user cannot transfer a template customization template#transfer_customization" do
+ post transfer_customization_org_admin_template_path(@org_template)
+ assert_unauthorized_redirect_to_root_path
+ sign_in @researcher
+ post transfer_customization_org_admin_template_path(@org_template)
+ assert_authorized_redirect_to_plans_page
end
- def verify_own_templates_table(user)
- assert_select "#organisation-templates table tbody" do |el|
- templates = Template.where(org: user.org, customization_of: nil)
-
- # Org Admins (funder or non-funder)
- if user.can_org_admin?
- # An Org Admin (for a non-funder Org) should only see their current templates in the own templates table
- templates.each do |template|
- # Expect to see the most current version of organisational templates
- current = Template.current(template.dmptemplate_id)
- if template == current
- assert el.to_s.include?(template.title), "expected #{user.email}'s own templates table to have the institutional template: '#{template.title}'"
- else
- assert_not el.to_s.include?(template.title), "expected #{user.email}'s own templates table to NOT have an older version of an the org's template: '#{template.title}'"
- end
- end
-
- # Expect to see no templates for other orgs in the own templates table
- Template.where.not(id: templates.collect(&:id)).each do |template|
- assert_not el.to_s.include?(template.title), " expected #{user.email}'s own templates table to NOT have: '#{template.title}'"
- end
-
- # Expect the funder templates table to contain NO 'Edit/Publish menus
- assert_not el.to_s.include?('Customise'), "expected #{user.email}'s own templates table to NOT contain any of the Customization menu items in the funder templates table"
- end
- end
+ test "authorized user can transfer a template customization template#transfer_customization" do
+# TODO: This will not work because Rails is persisting these transactions to the DB at the same time, so their created_at
+# timestamps match even if we add a 'sleep' statement. The template.upgrade_customization? will fail because of this.
+# sign_in @org_admin
+# original = @funder_template.customize!(@organisation)
+# # Add a phase to the funder template and republish it
+# phase = init_phase(@funder_template, { title: 'testing transfer of customizations' })
+# phase.template.update!({ published: true, title: 'upgraded funder template' })
+# post transfer_customization_org_admin_template_path(original)
+# assert_response :redirect
+# assert_redirected_to edit_org_admin_template_url(Template.latest_customized_version(@funder_template.family_id, @organisation.id).first)
end
- def verify_funder_templates_table(user)
- if user.org.funder_only?
- assert_select "#funder-templates table tbody", 0, "expected a funder only Org to NOT see the customizable table"
- else
- assert_select "#funder-templates table tbody" do |el|
- # An Org Admin should see all of the funder/default templates (except ones that belong to their org)
- templates = Template.where("(org_id IN (?) OR is_default = ?) AND org_id != ?", Org.where(org_type: [2,3]).collect(&:id), true, user.org.id)
- if user.can_org_admin?
- templates.each do |template|
- # Expect to only see published public templates
- if template.publicly_visible? && template.published?
- assert el.to_s.include?(template.title), "expected #{user.email}'s customizable table to have the funder (or default) template: '#{template.title}'"
- else
- assert_not el.to_s.include?(template.title), "expected #{user.email}'s customizable table to NOT have the unpublished/non-public funder template: '#{template.title}' (from org: #{template.org.abbreviation})"
- end
- end
-
- # Expect to see only the current org's customizations
- Template.where.not(id: templates.collect(&:id)).each do |template|
- if template.customization_of.nil?
- assert_not el.to_s.include?(template.title), "expected #{user.email}'s customizable table to NOT have the template from a non-funder org: '#{template.title}'"
- else
- if template.org == user.org
- assert el.to_s.include?(template.title), "expected #{user.email}'s customizable table to have their own customization: '#{template.title}'"
- else
- assert_not el.to_s.include?(template.title), "expected #{user.email}'s customizable table to NOT have a customization from another organisation: '#{template.title}'"
- end
- end
- end
- end
- end
- end
+ test "unauthorized user cannot get template#template_options" do
+ get "#{org_admin_template_options_path}?plan[org_id]=#{@institution.id}&plan[funder_id]=#{@funder.id}"
+ assert_unauthorized_redirect_to_root_path
end
- def verify_templates_table_scoping(path, selector, published, unpublished)
- get "#{path}?scope=published"
- assert_select "table tbody" do |el|
- published.each do |template|
- assert el.to_s.include?(template.title), "expected to see '#{template.title}' in #{selector} after clicking the 'published' predefined scope"
- end
- unpublished.each do |template|
- assert_not el.to_s.include?(template.title), "expected to NOT see '#{template.title}' in #{selector} after clicking the 'published' predefined scope"
- end
- end
-
- get "#{path}?scope=unpublished"
- assert_select "table tbody" do |el|
- published.each do |template|
- assert_not el.to_s.include?(template.title), "expected to NOT see '#{template.title}' in #{selector} after clicking the 'unpublished' predefined scope"
- end
- unpublished.each do |template|
- assert el.to_s.include?(template.title), "expected to see '#{template.title}' #{selector} after clicking the 'unpublished' predefined scope"
- end
- end
-
- get "#{path}?scope=all"
- assert_select "table tbody" do |el|
- published.each do |template|
- assert el.to_s.include?(template.title), "expected to see '#{template.title}' in #{selector} after clicking the 'all' predefined scope"
- end
- unpublished.each do |template|
- assert el.to_s.include?(template.title), "expected to see '#{template.title}' in #{selector} after clicking the 'all' predefined scope"
- end
- end
+ test "authorized user can get template#template_options" do
+ sign_in @researcher
+ get "#{org_admin_template_options_path}?plan[org_id]=#{@institution.id}&plan[funder_id]=#{@funder.id}"
+ assert_response :success
+ json_body = JSON.parse(@response.body)
+ assert json_body["templates"].length > 0
end
end
diff --git a/test/functional/phases_controller_test.rb b/test/functional/phases_controller_test.rb
deleted file mode 100644
index a7571b0..0000000
--- a/test/functional/phases_controller_test.rb
+++ /dev/null
@@ -1,234 +0,0 @@
-require 'test_helper'
-
-class PhasesControllerTest < ActionDispatch::IntegrationTest
-
- include Devise::Test::IntegrationHelpers
-
- setup do
- scaffold_template
-
- # Get the first Org Admin
- scaffold_org_admin(@template.org)
-
- @plan = Plan.create!(template: @template, title: 'Test Plan', visibility: :privately_visible,
- roles: [Role.new(user: @user, creator: true)])
- end
-
-# TODO: The following methods SHOULD replace the old 'admin_' prefixed methods. The routes file already has
-# these defined. They are defined multiple times though and we need to clean this up! In particular
-# look at the unnamed routes after 'new_plan_phase' below. They are not named because they are duplicates.
-# We should just have:
-#
-# SHOULD BE:
-# --------------------------------------------------
-# phases GET /templates/:template_id/phases phases#index
-# POST /templates/:template_id/phases phases#create
-# phase GET /templates/:template_id/phase/:id phases#show
-# PATCH /templates/:template_id/phase/:id phases#update
-# PUT /templates/:template_id/phase/:id phases#update
-# DELETE /templates/:template_id/phase/:id phases#destroy
-# edit_phase GET /templates/:template_id/phase/:id/edit phases#edit
-# new_phase GET /templates/:template_id/phase/new phases#new
-#
-# CURRENT RESULTS OF `rake routes`
-# --------------------------------------------------
-# admin_show_phase GET /org/admin/templates/phases/:id/admin_show(.:format) phases#admin_show
-# admin_preview_phase GET /org/admin/templates/phases/:id/admin_preview(.:format) phases#admin_preview
-# admin_add_phase GET /org/admin/templates/phases/:id/admin_add(.:format) phases#admin_add
-# admin_update_phase PUT /org/admin/templates/phases/:id/admin_update(.:format) phases#admin_update
-# admin_create_phase POST /org/admin/templates/phases/:id/admin_create(.:format) phases#admin_create
-# admin_destroy_phase DELETE /org/admin/templates/phases/:id/admin_destroy(.:format) phases#admin_destroy
-#
-# edit_plan_phase GET /plans/:plan_id/phases/:id/edit(.:format) phases#edit
-# status_plan_phase GET /plans/:plan_id/phases/:id/status(.:format) phases#status
-# plan_phase POST /plans/:plan_id/phases/:id/update(.:format) phases#update
-# plan_phases GET /plans/:plan_id/phases(.:format) phases#index
-# POST /plans/:plan_id/phases(.:format) phases#create
-# new_plan_phase GET /plans/:plan_id/phases/new(.:format) phases#new
-# GET /plans/:plan_id/phases/:id/edit(.:format) phases#edit
-# GET /plans/:plan_id/phases/:id(.:format) phases#show
-# PATCH /plans/:plan_id/phases/:id(.:format) phases#update
-# PUT /plans/:plan_id/phases/:id(.:format) phases#update
-# DELETE /plans/:plan_id/phases/:id(.:format) phases#destroy
-
-
-
- # GET /plans/:plan_id/phases/:id/edit (edit_plan_phase_path)
- # ----------------------------------------------------------
- test "show the edit phase page" do
- # Should redirect user to the root path if they are not logged in!
- get edit_plan_phase_path(@plan, @template.phases.first)
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- # TODO: Why does the policy check fail when @user is the creator and owner of @plan!?
- # Trying `@plan.assign_editor(@user)` doesn't work either!
- #get edit_plan_phase_path(@plan, @template.phases.first)
- #assert_response :success
-
- #assert assigns(:plan)
- #assert assigns(:phase)
- #assert assigns(:question_guidance)
- end
-
- # GET /plans/:plan_id/phases/:id/status (status_plan_phase_path)
- # ----------------------------------------------------------
- test "get the phase's status" do
- # Should redirect user to the root path if they are not logged in!
- get status_plan_phase_path(plan_id: @plan.id, id: @template.phases.first.id), format: :json
- assert_unauthorized_redirect_to_root_path
-
- @plan.assign_creator(@user)
- @plan.save!
- sign_in @user
-
- get status_plan_phase_path(plan_id: @plan.id, id: @template.phases.first.id), format: :json
- assert_response :success
- assert assigns(:plan)
- end
-
-# TODO: Why are we passing an :id here!? Its a new record but we seem to need the last template's id
- # GET /org/admin/templates/phases/:id/admin_show (admin_show_phase_path)
- # ----------------------------------------------------------
- test "show the phase" do
- # Should redirect user to the root path if they are not logged in!
- get admin_show_phase_path(@template.phases.first)
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- get admin_show_phase_path(@template.phases.first)
- assert_response :success
-
- assert assigns(:phase)
- end
-
- # GET /org/admin/templates/phases/:id/admin_preview (admin_preview_phase_path)
- # ----------------------------------------------------------
- test "preview the phase" do
- # Should redirect user to the root path if they are not logged in!
- get admin_preview_phase_path(@template.phases.first)
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- get admin_preview_phase_path(@template.phases.first)
- assert_response :success
-
- assert assigns(:template)
- assert assigns(:phase)
- end
-
- # GET /org/admin/templates/phases/:id/admin_add (admin_add_phase) Why do we have an id here!?
- # ----------------------------------------------------------
- test "show the new phase page" do
- # Should redirect user to the root path if they are not logged in!
- get admin_add_phase_path(@template.id)
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- get admin_add_phase_path(@template.id)
- assert_response :success
-
- assert assigns(:template)
- assert assigns(:phase)
- end
-
-# TODO: Why are we passing an :id here!? Its a new record but we seem to need the last template's id
- # POST /org/admin/templates/phases/:id/admin_create (admin_create_phase_path)
- # ----------------------------------------------------------
- test "create a phase " do
- params = {template_id: @template.id, title: 'Phase: Tester 2', number: 2}
-
- @template.dirty = false
- @template.save!
-
- # Should redirect user to the root path if they are not logged in!
- post admin_create_phase_path(@template.phases.first), {phase: params}
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- post admin_create_phase_path(@template.phases.first), {phase: params}
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('created')
- assert_response :redirect
- assert_redirected_to admin_show_phase_path(id: Phase.last.id, r: 'all-templates')
- assert assigns(:phase)
- assert_equal 'Phase: Tester 2', Phase.last.title, "expected the record to have been created!"
-
- # Make sure that the template's dirty flag got set
- assert @template.reload.dirty?, "expected the templates dirty flag to be true"
-
- # Invalid object
- post admin_create_phase_path(@template.phases.first), {phase: {template_id: @template.id}}
- assert flash[:alert].starts_with?(_('Could not create your'))
- assert_response :redirect
- assert assigns(:phase)
- assert assigns(:template)
- end
-
- # PUT /org/admin/templates/phases/:id/admin_update (admin_update_phase_path)
- # ----------------------------------------------------------
- test "update the phase" do
- params = {title: 'Phase - UPDATE'}
-
- @template.dirty = false
- @template.save!
-
- # Should redirect user to the root path if they are not logged in!
- put admin_update_phase_path(@template.phases.first), {phase: params}
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- # Valid save
- put admin_update_phase_path(@template.phases.first), {phase: params}
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('saved')
- assert_response :redirect
- assert_redirected_to admin_show_phase_url(@template.phases.first, r: 'all-templates')
- assert assigns(:phase)
- assert_equal 'Phase - UPDATE', @template.phases.first.title, "expected the record to have been updated"
-
- # Make sure that the template's dirty flag got set
- assert @template.reload.dirty?, "expected the templates dirty flag to be true"
-
- # Invalid save
- put admin_update_phase_path(@template.phases.first), {phase: {title: nil}}
- assert flash[:alert].starts_with?(_('Could not update your'))
- assert_response :redirect
- assert assigns(:phase)
- assert assigns(:template)
- assert assigns(:sections)
- assert assigns(:edit)
- end
-
- # DELETE /org/admin/templates/phases/:id/admin_destroy (admin_destroy_phase_path)
- # ----------------------------------------------------------
- test "delete the phase" do
- id = @template.phases.first.id
-
- @template.dirty = false
- @template.save!
-
- # Should redirect user to the root path if they are not logged in!
- # TODO: Why are we not just using id: here? shouldn't need to specify the key
- delete admin_destroy_phase_path(id: @template.phases.first.id, phase_id: id)
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- delete admin_destroy_phase_path(id: @template.phases.first.id, phase_id: id)
- assert_response :redirect
- assert_redirected_to edit_org_admin_template_path(@template, r: 'all-templates')
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('deleted')
- assert_raise ActiveRecord::RecordNotFound do
- Phase.find(id).nil?
- end
-
- # Make sure that the template's dirty flag got set
- assert @template.reload.dirty?, "expected the templates dirty flag to be true"
- end
-
-end
diff --git a/test/functional/public_pages_controller_test.rb b/test/functional/public_pages_controller_test.rb
index 6dd41a3..9531032 100644
--- a/test/functional/public_pages_controller_test.rb
+++ b/test/functional/public_pages_controller_test.rb
@@ -17,9 +17,9 @@
roles: [Role.new(user: User.last, creator: true)])
end
- @inst_tmplt = Template.create!(title: 'Inst template', org: Org.institution.first, migrated: false, published: true)
- @dflt_tmplt = Template.create!(title: 'Dflt template', org: Org.managing_orgs.first, migrated: false, published: true)
- @fndr_tmplt = Template.create!(title: 'Fndr template', org: Org.funder.first, migrated: false, published: true)
+ @inst_tmplt = Template.create!(title: 'Inst template', org: Org.institution.first, archived: false, published: true)
+ @dflt_tmplt = Template.create!(title: 'Dflt template', org: Org.managing_orgs.first, archived: false, published: true)
+ @fndr_tmplt = Template.create!(title: 'Fndr template', org: Org.funder.first, archived: false, published: true)
[@inst_tmplt, @dflt_tmplt, @fndr_tmplt].each do |t|
t.published = true
@@ -77,31 +77,31 @@
get public_templates_path
assert_response :success
assert assigns(:templates)
- assert @response.body.include?(template_export_path(@fndr_tmplt.dmptemplate_id)), "expected to see the funder template download link when NOT logged in"
- assert @response.body.include?(template_export_path(@dflt_tmplt.dmptemplate_id)), "expected to see the default template download link when NOT logged in"
- assert_not @response.body.include?(template_export_path(@inst_tmplt.dmptemplate_id)), "expected to NOT see the institution template download link when NOT logged in"
+ assert @response.body.include?(template_export_path(@fndr_tmplt.family_id)), "expected to see the funder template download link when NOT logged in"
+ assert @response.body.include?(template_export_path(@dflt_tmplt.family_id)), "expected to see the default template download link when NOT logged in"
+ assert_not @response.body.include?(template_export_path(@inst_tmplt.family_id)), "expected to NOT see the institution template download link when NOT logged in"
# Verify the same results are received when the user is logged in
sign_in @user
get public_templates_path
assert_response :success
assert assigns(:templates)
- assert @response.body.include?(template_export_path(@fndr_tmplt.dmptemplate_id)), "expected to see the funder template download link when NOT logged in"
- assert @response.body.include?(template_export_path(@dflt_tmplt.dmptemplate_id)), "expected to see the default template download link when NOT logged in"
- assert_not @response.body.include?(template_export_path(@inst_tmplt.dmptemplate_id)), "expected to NOT see the institution template download link when NOT logged in"
+ assert @response.body.include?(template_export_path(@fndr_tmplt.family_id)), "expected to see the funder template download link when NOT logged in"
+ assert @response.body.include?(template_export_path(@dflt_tmplt.family_id)), "expected to see the default template download link when NOT logged in"
+ assert_not @response.body.include?(template_export_path(@inst_tmplt.family_id)), "expected to NOT see the institution template download link when NOT logged in"
end
# TODO: Need to install the wkhtmltopdf library on Travis for this to work!
- # GET /template_export/:dmptemplate_id (template_export_path)
+ # GET /template_export/:family_id (template_export_path)
# ----------------------------------------------------------
test 'export a public template' do
-# get template_export_path(@fndr_tmplt.dmptemplate_id, format: :pdf)
+# get template_export_path(@fndr_tmplt.family_id, format: :pdf)
# assert_response :success
-# get template_export_path(@dflt_tmplt.dmptemplate_id, format: :pdf)
+# get template_export_path(@dflt_tmplt.family_id, format: :pdf)
# assert_response :success
-# get template_export_path(@inst_tmplt.dmptemplate_id, format: :pdf)
+# get template_export_path(@inst_tmplt.family_id, format: :pdf)
# assert_response :redirect
# assert_equal "You need to sign in or sign up before continuing.", flash[:alert]
# assert_redirected_to root_path
diff --git a/test/functional/questions_controller_test.rb b/test/functional/questions_controller_test.rb
deleted file mode 100644
index bbe42f4..0000000
--- a/test/functional/questions_controller_test.rb
+++ /dev/null
@@ -1,149 +0,0 @@
-require 'test_helper'
-
-class QuestionsControllerTest < ActionDispatch::IntegrationTest
-
- include Devise::Test::IntegrationHelpers
-
- setup do
- scaffold_template
- @section = @template.phases.first.sections.first
-
- # Get the first Org Admin
- scaffold_org_admin(@template.org)
-
- @question_format = QuestionFormat.where(option_based: false).first
- end
-
-# TODO: The following methods SHOULD replace the old 'admin_' prefixed methods. The routes file already has
-# these defined. They are defined multiple times though and we need to clean this up! In particular
-# look at the unnamed routes after 'new_plan_phase' below. They are not named because they are duplicates.
-# We should just have:
-#
-# SHOULD BE:
-# --------------------------------------------------
-# questions GET /templates/:template_id/phases/:phase_id/sections/:section_id/questions sections#index
-# POST /templates/:template_id/phases/:phase_id/sections/:section_id/questions sections#create
-# question GET /templates/:template_id/phases/:phase_id/section/:section_id/questions/:id sections#show
-# PATCH /templates/:template_id/phases/:phase_id/section/:section_id/questions/:id sections#update
-# PUT /templates/:template_id/phases/:phase_id/section/:section_id/questions/:id sections#update
-# DELETE /templates/:template_id/phases/:phase_id/section/:section_id/questions/:id sections#destroy
-#
-# CURRENT RESULTS OF `rake routes`
-# --------------------------------------------------
-# admin_create_question POST /org/admin/templates/questions/:id/admin_create questions#admin_create
-# admin_update_question PUT /org/admin/templates/questions/:id/admin_update questions#admin_update
-# admin_destroy_question DELETE /org/admin/templates/questions/:id/admin_destroy questions#admin_destroy
-
-
- # POST /org/admin/templates/questions/:id/admin_create (admin_create_question_path)
- # ----------------------------------------------------------
- test "create a new question" do
- params = {section_id: @section.id, text: 'Test Question', number: 9, question_format_id: @question_format.id}
-
- @section.phase.template.dirty = false
- @section.phase.template.save!
-
- # Should redirect user to the root path if they are not logged in!
- post admin_create_question_path(@section), {question: params}
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
- @new_question = Question.new
- @new_question.number = @section.questions.count + 1
- example_answer = @new_question.annotations.build
- example_answer.type = :example_answer
- example_answer.save
- post admin_create_question_path(@section), {question: params}
- assert_response :redirect
- assert assigns(:question)
- assert_redirected_to admin_show_phase_url(id: @section.phase.id, section_id: @section.id, question_id: Question.last.id, r: 'all-templates')
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('created')
- assert_equal 'Test Question', Question.last.text, "expected the record to have been created!"
-
- # Make sure that the template's dirty flag got set
- assert @section.phase.template.reload.dirty?, "expected the templates dirty flag to be true"
-
- # Invalid object
- post admin_create_question_path(@section), {question: {section_id: @section.id, text: nil, question_format_id: @question_format.id}}
- assert flash[:alert].starts_with?(_('Could not create your'))
- assert_response :redirect
- assert assigns(:question)
- assert assigns(:section)
- assert assigns(:phase)
- assert assigns(:edit)
- assert assigns(:open)
- assert assigns(:sections)
- assert assigns(:section_id)
- end
-
- # PUT /org/admin/templates/questions/:id/admin_update (admin_update_question_path)
- # ----------------------------------------------------------
- test "update the question" do
- params = {text: 'Question - UPDATE'}
-
- @section.phase.template.dirty = false
- @section.phase.template.save!
-
- # Should redirect user to the root path if they are not logged in!
- put admin_update_question_path(@section.questions.first), {question: params}
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- # Valid save
- put admin_update_question_path(@section.questions.first), {question: params}
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('saved')
- assert_response :redirect
- assert_redirected_to admin_show_phase_url(id: @section.phase.id, section_id: @section.id, question_id: @section.questions.first.id, r: 'all-templates')
- assert assigns(:phase)
- assert assigns(:section)
- assert assigns(:question)
- assert_equal 'Question - UPDATE', @section.questions.first.text, "expected the record to have been updated"
-
- # Make sure that the template's dirty flag got set
- assert @section.phase.template.reload.dirty?, "expected the templates dirty flag to be true"
-
- # Invalid save
- put admin_update_question_path(@section.questions.first), {question: {text: nil}}
- assert flash[:alert].starts_with?(_('Could not update your'))
- assert_response :redirect
- assert assigns(:question)
- assert assigns(:section)
- assert assigns(:phase)
- assert assigns(:edit)
- assert assigns(:open)
- assert assigns(:sections)
- assert assigns(:section_id)
- assert assigns(:question_id)
- end
-
- # DELETE /org/admin/templates/questions/:id/admin_destroy (admin_destroy_question_path)
- # ----------------------------------------------------------
- test "delete the question" do
- id = @section.questions.first.id
-
- @section.phase.template.dirty = false
- @section.phase.template.save!
-
- # Should redirect user to the root path if they are not logged in!
- delete admin_destroy_question_path(id: @section.id, question_id: id)
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- delete admin_destroy_question_path(id: @section.id, question_id: id)
- assert_response :redirect
- assert assigns(:phase)
- assert assigns(:section)
- assert assigns(:question)
- assert_redirected_to admin_show_phase_url(id: @section.phase.id, section_id: @section.id, r: 'all-templates')
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('deleted')
- assert_raise ActiveRecord::RecordNotFound do
- Question.find(id).nil?
- end
-
- # Make sure that the template's dirty flag got set
- assert @section.phase.template.reload.dirty?, "expected the templates dirty flag to be true"
- end
-
-end
\ No newline at end of file
diff --git a/test/functional/sections_controller_test.rb b/test/functional/sections_controller_test.rb
deleted file mode 100644
index 5ee66de..0000000
--- a/test/functional/sections_controller_test.rb
+++ /dev/null
@@ -1,135 +0,0 @@
-require 'test_helper'
-
-class SectionsControllerTest < ActionDispatch::IntegrationTest
-
- include Devise::Test::IntegrationHelpers
-
- setup do
- scaffold_template
- @phase = @template.phases.first
-
- # Get the first Org Admin
- scaffold_org_admin(@template.org)
- end
-
-# TODO: The following methods SHOULD replace the old 'admin_' prefixed methods. The routes file already has
-# these defined. They are defined multiple times though and we need to clean this up! In particular
-# look at the unnamed routes after 'new_plan_phase' below. They are not named because they are duplicates.
-# We should just have:
-#
-# SHOULD BE:
-# --------------------------------------------------
-# sections GET /templates/:template_id/phases/:phase_id/sections sections#index
-# POST /templates/:template_id/phases/:phase_id/sections sections#create
-# section GET /templates/:template_id/phases/:phase_id/section/:id sections#show
-# PATCH /templates/:template_id/phases/:phase_id/section/:id sections#update
-# PUT /templates/:template_id/phases/:phase_id/section/:id sections#update
-# DELETE /templates/:template_id/phases/:phase_id/section/:id sections#destroy
-#
-# CURRENT RESULTS OF `rake routes`
-# --------------------------------------------------
-# admin_create_section POST /org/admin/templates/sections/:id/admin_create sections#admin_create
-# admin_update_section PUT /org/admin/templates/sections/:id/admin_update sections#admin_update
-# admin_destroy_section DELETE /org/admin/templates/sections/:id/admin_destroy sections#admin_destroy
-
-
-
- # POST /org/admin/templates/sections/:id/admin_create (admin_create_section_path)
- # ----------------------------------------------------------
- test "create a new section" do
- params = {phase_id: @phase.id, title: 'Section Tester', number: 99}
-
- @phase.template.dirty = false
- @phase.template.save!
-
- # Should redirect user to the root path if they are not logged in!
- post admin_create_section_path(@phase), {section: params}
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- post admin_create_section_path(@phase), {section: params}
- assert_response :redirect
- assert_redirected_to admin_show_phase_url(id: @phase.id, section_id: Section.last.id, r: 'all-templates')
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('created')
- assert_equal 'Section Tester', Section.last.title, "expected the record to have been created!"
-
- # Make sure that the template's dirty flag got set
- assert @phase.template.reload.dirty?, "expected the templates dirty flag to be true"
-
- # Invalid object
- post admin_create_section_path(@phase), {section: {phase_id: @phase.id, title: nil}}
- assert flash[:alert].starts_with?(_('Could not create your'))
- assert_response :redirect
- assert assigns(:section)
- assert assigns(:phase)
- assert assigns(:edit)
- assert assigns(:open)
- assert assigns(:sections)
- end
-
- # PUT /org/admin/templates/sections/:id/admin_update (admin_update_section_path)
- # ----------------------------------------------------------
- test "update the section" do
- params = {title: 'Phase - UPDATE'}
-
- @phase.template.dirty = false
- @phase.template.save!
-
- # Should redirect user to the root path if they are not logged in!
- put admin_update_section_path(@phase.sections.first), {section: params}
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- # Valid save
- put admin_update_section_path(@phase.sections.first), {section: params}
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('saved')
- assert_response :redirect
- assert_redirected_to admin_show_phase_url(id: @phase.id, section_id: @phase.sections.first.id, r: 'all-templates')
- assert_equal 'Phase - UPDATE', @phase.sections.first.title, "expected the record to have been updated"
-
- # Make sure that the template's dirty flag got set
- assert @phase.template.reload.dirty?, "expected the templates dirty flag to be true"
-
- # Invalid save
- put admin_update_section_path(@phase.sections.first), {section: {title: nil}}
- assert flash[:alert].starts_with?(_('Could not update your'))
- assert_response :redirect
- assert assigns(:section)
- assert assigns(:phase)
- assert assigns(:edit)
- assert assigns(:open)
- assert assigns(:sections)
- assert assigns(:section_id)
- end
-
- # DELETE /org/admin/templates/sections/:id/admin_destroy (admin_destroy_section_path)
- # ----------------------------------------------------------
- test "delete the section" do
- id = @phase.sections.first.id
-
- @phase.template.dirty = false
- @phase.template.save!
-
- # Should redirect user to the root path if they are not logged in!
- delete admin_destroy_section_path(id: @phase.id, section_id: id)
- assert_unauthorized_redirect_to_root_path
-
- sign_in @user
-
- delete admin_destroy_section_path(id: @phase.id, section_id: id)
- assert_response :redirect
- assert assigns(:section)
- assert assigns(:phase)
- assert_redirected_to admin_show_phase_url(id: @phase.id, r: 'all-templates')
- assert flash[:notice].start_with?('Successfully') && flash[:notice].include?('deleted')
- assert_raise ActiveRecord::RecordNotFound do
- Section.find(id).nil?
- end
-
- # Make sure that the template's dirty flag got set
- assert @phase.template.reload.dirty?, "expected the templates dirty flag to be true"
- end
-
-end
\ No newline at end of file
diff --git a/test/helpers/application_helper_test.rb b/test/helpers/application_helper_test.rb
index 136e014..0c5ca2b 100644
--- a/test/helpers/application_helper_test.rb
+++ b/test/helpers/application_helper_test.rb
@@ -20,7 +20,7 @@
test "resource should return contents of instance variable @resource OR a new User" do
# If @resource is not set then we should receive a new User
assert resource.is_a?(User), "Expected resource() to return a new User"
- assert_equal nil, resource.id, "Expected resource() to return a User with an Id"
+ assert_nil resource.id, "Expected resource() to return a User with an Id"
# If @resource is set then we should receive that object
@resource = Org.first
diff --git a/test/integration/download_plan_path_test.rb b/test/integration/download_plan_path_test.rb
new file mode 100644
index 0000000..cb6521e
--- /dev/null
+++ b/test/integration/download_plan_path_test.rb
@@ -0,0 +1,67 @@
+require 'test_helper'
+
+class DownloadPlanPathTest < ActionDispatch::IntegrationTest
+ include Devise::Test::IntegrationHelpers
+
+ setup do
+ @org = init_organisation
+ template = init_template(@org)
+ phase = init_phase(template)
+ section = init_section(phase)
+ init_question(section)
+ @plan = init_plan(template)
+ @user = User.create(user_seed.merge({ org: @org }))
+ end
+
+ def assert_download_link_present(plan, user)
+ sign_in user
+ get(download_plan_path(plan))
+ links = css_select("a[href=\"#{download_plan_path(plan)}\"]")
+ refute_empty(links)
+ assert_equal(links[0].text, _('Download'))
+ end
+
+ def refute_download_link_present(plan, user)
+ sign_in user
+ get(download_plan_path(plan))
+ links = css_select("a[href=\"#{download_plan_path(plan)}\"]")
+ assert_empty(links)
+ end
+
+ test 'download tab is visible when user has role creator, administrator, commenter, editor on the plan' do
+ assign_roles = [
+ lambda{ |plan, user| plan.assign_creator(user.id) },
+ lambda{ |plan, user| plan.assign_administrator(user.id) },
+ lambda{ |plan, user| plan.assign_editor(user.id) },
+ lambda{ |plan, user| plan.assign_reader(user.id) }
+ ]
+ assign_roles.each do |assign_role|
+ assign_role.call(@plan, @user)
+ assert_download_link_present(@plan, @user)
+ end
+ end
+
+ test 'download tab is visible when user is super_admin' do
+ @user.perms = Perm.all
+ assert_download_link_present(@plan, @user)
+ end
+
+ test 'download tab is visible when user is an org_admin from the same org that any owner\'s org' do
+ @plan.assign_creator(@user.id)
+ user2 = User.create(user_seed.merge({ org: @org, email: 'foo@bar.com' }))
+ user2.perms << Perm.grant_permissions
+ assert_download_link_present(@plan, user2)
+ end
+
+ test 'download tab is NOT visible when user is an org_admin from an org different from every owner\'s org' do
+ @plan.assign_creator(@user.id)
+ user2 = User.create(user_seed.merge({ org: init_funder_organisation, email: 'foo@bar.com' }))
+ user2.perms << Perm.grant_permissions
+ refute_download_link_present(@plan, user2)
+ end
+
+ test 'download tab is NOT visible when user is not super_admin nor org_admin nor has commenter role' do
+ @plan.roles << Role.new(user_id: @user.id, reviewer: true)
+ refute_download_link_present(@plan, @user)
+ end
+end
\ No newline at end of file
diff --git a/test/integration/template_selection_test.rb b/test/integration/template_selection_test.rb
index 7f3bfb8..af69cd4 100644
--- a/test/integration/template_selection_test.rb
+++ b/test/integration/template_selection_test.rb
@@ -4,167 +4,164 @@
include Devise::Test::IntegrationHelpers
setup do
- scaffold_template
- @template = Template.default
-
- @researcher = User.last
- scaffold_org_admin(@template.org)
-
- @funder = Org.find_by(org_type: 2)
- @funder_template = @funder.templates.where(published: true).first #Template.create(title: 'Funder template', org: @funder, migrated: false)
- # Template can't be published on creation so do it afterward
- @funder_template.published = true
- @funder_template.visibility = Template.visibilities[:publicly_visible]
- @funder_template.save
-
- @org = @researcher.org
- @org_template = Template.create(title: 'Org template', org: @org, migrated: false)
- # Template can't be published on creation so do it afterward
- @org_template.published = true
- @org_template.visibility = Template.visibilities[:organisationally_visible]
- @org_template.save
+ # Need to clear the tables until we get seed.rb out of test_helper.rb
+ Template.delete_all
+
+ @funder = init_funder
+ @institution = init_institution
+ @organisation = init_organisation
+ @funder2 = init_funder({ name: 'Funder 2', abbreviation: 'F2' })
+
+ @researcher = init_researcher(@institution)
+ @org_admin = init_org_admin(@institution)
+
+ @funder_published_public_template = init_template(@funder, {
+ title: 'Test Funder public Template',
+ published: true
+ })
+ @funder_published_private_template = init_template(@funder, {
+ title: 'Test Funder private Template',
+ published: true
+ })
+ # funder templates are public by default on creation so set it to organisationally_visible afterward
+ @funder_published_private_template.update!({ visibility: Template.visibilities[:organisationally_visible] })
+ @funder_unpublished_template = init_template(@funder, {
+ title: 'Test Funder unpublished Template',
+ published: false
+ })
+ @funder2_published_public_template = init_template(@funder2, {
+ title: 'Test Funder 2 Template',
+ published: true
+ })
+ @org_published_private_template = init_template(@institution, {
+ title: 'Test Org Template',
+ published: true
+ })
+ @default_published_private_template = init_template(@organisation, {
+ title: 'Default Template',
+ published: true,
+ is_default: true
+ })
+ end
+
+ # ----------------------------------------------------------
+ test 'new plan gets published versions of templates not the latest version' do
+ version = @org_published_private_template.generate_version!
+ sign_in @researcher
+ get "#{org_admin_template_options_path}?plan[org_id]=#{@institution.id}"
+ json = JSON.parse(@response.body)
+ assert_equal 1, json['templates'].size, "expected 1 template but got: #{json['templates'].collect{|h| h['title'] }.join(', ')}"
+ assert_equal @org_published_private_template.id, json['templates'][0]['id'], 'expected the published version of the template'
end
# ----------------------------------------------------------
- test 'plan gets publish versions of templates' do
- original_id = @template.id
- template = version_template(@template)
-
+ test 'new plan gets default template when no funder or research org is specified' do
sign_in @researcher
-
- get "#{org_admin_template_options_path}?plan[org_id]=#{@template.org_id}"
- assert_response :success
+ get "#{org_admin_template_options_path}?plan[org_id]=&plan[funder_id]="
json = JSON.parse(@response.body)
-
- assert_equal 1, json['templates'].size
- assert_equal original_id, json['templates'][0]['id']
- assert_equal original_id, Template.live(@template.dmptemplate_id).id
-
- # Version the template again
- original_id = template.id
- template = version_template(template)
-
- # Make sure the published version is used
- get "#{org_admin_template_options_path}?plan[org_id]=#{@template.org_id}"
- assert_response :success
- json = JSON.parse(@response.body)
-
- assert_equal 1, json['templates'].size
- assert_equal original_id, json['templates'][0]['id']
- assert_equal original_id, Template.live(@template.dmptemplate_id).id
-
- # Update the template and make sure the published version stayed the same
- sign_in @user
- put org_admin_template_path(template), {template: {title: "Blah blah blah"}}
-
- sign_in @researcher
-
- get "#{org_admin_template_options_path}?plan[org_id]=#{@template.org_id}"
- assert_response :success
- json = JSON.parse(@response.body)
-
- assert_equal 1, json['templates'].size
- assert_equal original_id, json['templates'][0]['id']
- assert_equal original_id, Template.live(@template.dmptemplate_id).id
+ assert_equal 1, json['templates'].size, "expected 1 template but got: #{json['templates'].collect{|h| h['title'] }.join(', ')}"
+ assert_equal @default_published_private_template.id, json['templates'][0]['id'], 'expected the default template'
end
# ----------------------------------------------------------
- test 'plan gets generic template when no funder or org' do
- temp = Template.find_by(published: true, is_default: true)
- if temp.blank?
- @template.is_default = true
- @template.save!
- temp = @template
- end
-
+ test 'new plan gets org template when a research org is specified but no funder is specified' do
sign_in @researcher
- get "#{org_admin_template_options_path}?plan[org_id]="
- assert_response :success
+ get "#{org_admin_template_options_path}?plan[org_id]=#{@institution.id}&plan[funder_id]="
json = JSON.parse(@response.body)
-
- assert_equal 1, json['templates'].size
- assert_equal @template.id, json['templates'][0]['id']
+ assert_equal 1, json['templates'].size, "expected 1 template but got: #{json['templates'].collect{|h| h['title'] }.join(', ')}"
+ assert_equal @org_published_private_template.id, json['templates'][0]['id'], 'expected 1 org template'
end
# ----------------------------------------------------------
- test 'plan gets org template when no funder' do
+ test 'new plan gets multiple org templates when a research org is specified but no funder is specified' do
+ template2 = init_template(@institution, {
+ title: 'Test Org Template 2',
+ published: true,
+ is_default: false,
+ })
+ template2.update!(visibility: Template.visibilities[:organisationally_visible])
sign_in @researcher
- get "#{org_admin_template_options_path}?plan[org_id]=#{@org.id}&plan[funder_id]="
-
- assert_response :success
+ get "#{org_admin_template_options_path}?plan[org_id]=#{@institution.id}&plan[funder_id]="
json = JSON.parse(@response.body)
-
- assert_equal 1, json['templates'].size
- assert_equal @org_template.id, json['templates'][0]['id']
+ assert_equal 2, json['templates'].size, "expected 2 templates but got: #{json['templates'].collect{|h| h['title'] }.join(', ')}"
+ json['templates'].each{ |h| assert [@org_published_private_template.id, template2.id].include?(h['id']), 'expected the json to include only the 2 org templates' }
end
# ----------------------------------------------------------
- test 'plan gets funder template when no org' do
+ test 'new plan gets public funder template when no research org is specified' do
sign_in @researcher
get "#{org_admin_template_options_path}?plan[org_id]=&plan[funder_id]=#{@funder.id}"
-
- assert_response :success
json = JSON.parse(@response.body)
-
- assert_equal 1, json['templates'].size
- assert_equal @funder_template.id, json['templates'][0]['id']
+ assert_equal 1, json['templates'].size, "expected 1 template but got: #{json['templates'].collect{|h| h['title'] }.join(', ')}"
+ assert_equal @funder_published_public_template.id, json['templates'][0]['id'], 'expected the funder template'
end
# ----------------------------------------------------------
- test 'plan gets funder template when org has no customization' do
+ test 'new plan gets multiple public funder templates when no research org is specified' do
+ template2 = init_template(@funder, {
+ title: 'Test Funder Template 2',
+ published: true,
+ is_default: false,
+ visibility: Template.visibilities[:publicly_visible]
+ })
sign_in @researcher
-
- get "#{org_admin_template_options_path}?plan[org_id]=#{@org.id}&plan[funder_id]=#{@funder.id}"
- assert_response :success
+ get "#{org_admin_template_options_path}?plan[org_id]=&plan[funder_id]=#{@funder.id}"
json = JSON.parse(@response.body)
-
- assert_equal 1, json['templates'].size
- assert_equal @funder_template.id, json['templates'][0]['id']
+ assert_equal 2, json['templates'].size, "expected 2 templates but got: #{json['templates'].collect{|h| h['title'] }.join(', ')}"
+ json['templates'].each{ |h| assert [@funder_published_public_template.id, template2.id].include?(h['id']), 'expected the json to include only the 2 funder templates' }
+ end
+
+ # ----------------------------------------------------------
+ test 'new plan gets both the public funder template when both research org and funder are specified' do
+ sign_in @researcher
+ get "#{org_admin_template_options_path}?plan[org_id]=#{@institution.id}&plan[funder_id]=#{@funder.id}"
+ json = JSON.parse(@response.body)
+ assert_equal 1, json['templates'].size, "expected 1 template but got: #{json['templates'].collect{|h| h['title'] }.join(', ')}"
+ assert_equal @funder_published_public_template.id, json['templates'][0]['id'], 'expected the funder template'
end
# ----------------------------------------------------------
- test 'plan gets customized version of funder template' do
- customization = Template.create(title: 'Customization', org: @org)
- # Template can't be published on creation so do it afterward
- customization.published = true
- customization.visibility = Template.visibilities[:organisationally_visible]
- customization.customization_of = @funder_template.dmptemplate_id
- customization.save
-
+ test 'new plan gets the customized version of funder template when the specified research org has customized it' do
+ customization = @funder_published_public_template.customize!(@institution)
+ customization.update!(title: 'Customization test', published: true)
sign_in @researcher
-
- get "#{org_admin_template_options_path}?plan[org_id]=#{@org.id}&plan[funder_id]=#{@funder.id}"
- assert_response :success
+ get "#{org_admin_template_options_path}?plan[org_id]=#{@institution.id}&plan[funder_id]=#{@funder.id}"
json = JSON.parse(@response.body)
+ assert_equal 1, json['templates'].size, "expected 1 template but got: #{json['templates'].collect{|h| h['title'] }.join(', ')}"
+ assert_equal customization.id, json['templates'][0]['id'], 'expected the customization of the funder template'
+ end
- assert_equal 1, json['templates'].size
- assert_equal customization.id, json['templates'][0]['id']
- end
-
# ----------------------------------------------------------
- test 'list of templates is returned when the funder has multiples' do
- funder_template2 = Template.create(title: 'Funder template 2', org: @funder)
- # Template can't be published on creation so do it afterward
- funder_template2.published = true
- funder_template2.visibility = Template.visibilities[:publicly_visible]
- funder_template2.save
-
+ test 'plan gets choice between multiple funder templates when both research org and funder are specified and both the org and funder have multiple templates' do
+ funder_template2 = init_template(@funder, { title: 'Funder template 2', published: true, visibility: Template.visibilities[:publicly_visible] })
+ org_template2 = init_template(@institution, { title: 'Org template 2', published: true, visibility: Template.visibilities[:organisationally_visible] })
sign_in @researcher
-
- get "#{org_admin_template_options_path}?plan[org_id]=#{@org.id}&plan[funder_id]=#{@funder.id}"
- assert_response :success
+ get "#{org_admin_template_options_path}?plan[org_id]=#{@institution.id}&plan[funder_id]=#{@funder.id}"
json = JSON.parse(@response.body)
-
- assert_equal 2, json['templates'].size
- assert_equal @funder_template.id, json['templates'][0]['id']
- assert_equal funder_template2.id, json['templates'][1]['id']
+ assert_equal 2, json['templates'].size, "expected 2 templates but got: #{json['templates'].collect{|h| h['title'] }.join(', ')}"
+ json['templates'].each{ |h| assert [@funder.id, funder_template2.id].include?(h['id']), 'expected the json to include only the funder templates' }
end
-
-
- private
- # ----------------------------------------------------------
- def version_template(template)
- get publish_org_admin_template_path(template)
- Template.current(template.dmptemplate_id)
- end
+
+ # ----------------------------------------------------------
+ test 'new plan gets default template when combination of specified funder and research org have no templates' do
+ @org_published_private_template.destroy!
+ @funder_published_public_template.destroy!
+ sign_in @researcher
+ get "#{org_admin_template_options_path}?plan[org_id]=#{@institution.id}&plan[funder_id]=#{@funder.id}"
+ json = JSON.parse(@response.body)
+ assert_equal 1, json['templates'].size, "expected 1 template but got: #{json['templates'].collect{|h| h['title'] }.join(', ')}"
+ assert_equal @default_published_private_template.id, json['templates'][0]['id'], 'expected the default template'
+ end
+
+ # ----------------------------------------------------------
+ test 'new plan gets customized version of the default template if the research org has no template of its own but has customized the default template' do
+ @org_published_private_template.destroy
+ customization = @default_published_private_template.customize!(@institution)
+ customization.update!(title: 'Default template customization test', published: true)
+ sign_in @researcher
+ get "#{org_admin_template_options_path}?plan[org_id]=#{@institution.id}&plan[funder_id]="
+ json = JSON.parse(@response.body)
+ assert_equal 1, json['templates'].size, "expected 1 template but got: #{json['templates'].collect{|h| h['title'] }.join(', ')}"
+ assert_equal customization.id, json['templates'][0]['id'], "expected the customized version of the default template"
+ end
end
diff --git a/test/integration/template_versioning_test.rb b/test/integration/template_versioning_test.rb
deleted file mode 100644
index 6de1c8a..0000000
--- a/test/integration/template_versioning_test.rb
+++ /dev/null
@@ -1,77 +0,0 @@
-require 'test_helper'
-
-class TemplateVersioningTest < ActionDispatch::IntegrationTest
- include Devise::Test::IntegrationHelpers
-
- setup do
- scaffold_template
- scaffold_org_admin(@template.org)
-
- sign_in @user
-
- # Make sure the template starts out as unpublished. The controller will not allow changes once its published
- @template.published = false
- @template.save!
-
- @initial_id = @template.id
- @initial_version = @template.version
- @initial_title = @template.title
- @dmptemplate_id = @template.dmptemplate_id
- end
-
- # ----------------------------------------------------------
- test 'template gets versioned when its phases are modified and it is already published' do
- @template.dirty = false
- @template.save!
-
- put admin_update_phase_path @template.phases.first, {phase: {title: 'UPDATED'}}
- @template.reload
- assert @template.dirty
- end
-
- # ----------------------------------------------------------
- test 'template gets versioned when its sections are modified and it is already published' do
- @template.dirty = false
- @template.save!
-
- put admin_update_section_path @template.phases.first.sections.first, {section: {title: 'UPDATED'}}
- @template.reload
- assert @template.dirty
- end
-
- # ----------------------------------------------------------
- test 'template gets versioned when its questions are modified and it is already published' do
- @template.dirty = false
- @template.save!
-
- put admin_update_question_path @template.phases.first.sections.first.questions.first, {question: {text: 'UPDATED'}}
- @template.reload
- assert @template.dirty
- end
-
- # ----------------------------------------------------------
- test 'template does NOT get versioned if its unpublished' do
- # Change the title after its been published
- put org_admin_template_path(@template), {template: {title: "Blah blah blah"}}
- @template = Template.current(@dmptemplate_id)
-
- assert_equal @initial_version, @template.version, "expected the version to have stayed the same"
- assert_equal @initial_id, @template.id, "expected the id to been the same"
- assert_equal @dmptemplate_id, @template.dmptemplate_id, "expected the dmptemplate_id to match"
- assert_equal false, @template.published?, "expected the version to have remained unpublished"
- end
-
- # ----------------------------------------------------------
- test 'publishing a plan unpublishes the old published plan' do
- get publish_org_admin_template_path(@template)
- assert_not Template.live(@dmptemplate_id).nil?
- assert_equal 1, Template.where(org: @user.org, dmptemplate_id: @dmptemplate_id, published: true).count
- end
-
- # ----------------------------------------------------------
- test 'unpublishing a plan makes all historical versions unpublished' do
- get publish_org_admin_template_path(@template)
- get unpublish_org_admin_template_path(@template)
- assert Template.live(@dmptemplate_id).nil?
- end
-end
diff --git a/test/mailers/previews/user_mailer_preview.rb b/test/mailers/previews/user_mailer_preview.rb
index ab7cd42..d3949b2 100644
--- a/test/mailers/previews/user_mailer_preview.rb
+++ b/test/mailers/previews/user_mailer_preview.rb
@@ -8,7 +8,7 @@
password: "password123", password_confirmation: "password123", org: @org,
accept_terms: true, confirmed_at: Time.zone.now)
@template = Template.new(title: 'Test template', description: 'My test template', org: @org,
- migrated: false, dmptemplate_id: "9999999")
+ archived: false, family_id: "9999999")
@plan = Plan.new(template: @template, title: 'Test Plan', grant_number: 'Grant-123',
principal_investigator: 'Researcher', principal_investigator_identifier: 'researcher-1234',
description: "this is my plan's informative description",
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 99ef6ab..0c0f4c7 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -27,6 +27,303 @@
# Sometimes TravisCI fails when accessing the LANGUAGES array, so reload it here if necessary
LANGUAGES = Language.all if LANGUAGES.empty?
+ # Default attributes for model initialization
+ def org_seed
+ { name: 'Test Institution',
+ abbreviation: 'TST',
+ org_type: Org.org_type_values_for(:institution).min,
+ target_url: 'http://test-funder.org',
+ language: LANGUAGES.first,
+ contact_email: 'help.desk@test-funder.org',
+ contact_name: 'Help Desk',
+ links: {"org":[{"link":"http://dmproadmap.org","text":"DMPRoadmap"}]},
+ }
+ end
+ def user_seed
+ {
+ email: 'test-user@testing-roadmap.org',
+ firstname: 'Test',
+ surname: 'User',
+ language: Language.find_by(abbreviation: FastGettext.locale),
+ password: "password123",
+ password_confirmation: "password123",
+ accept_terms: true,
+ confirmed_at: Time.zone.now,
+ }
+ end
+
+ def template_seed
+ {
+ title: 'Test template',
+ description: 'this is a test template',
+ org: Org.first,
+ }
+ end
+ def phase_seed
+ {
+ title: 'Test phase',
+ description: 'This is a phase used for testing',
+ number: 1,
+ modifiable: true,
+ }
+ end
+ def section_seed
+ {
+ title: 'Test section',
+ description: 'This is a section used for testing',
+ number: 1,
+ modifiable: true,
+ }
+ end
+ def question_format_seed
+ {
+ title: 'Text area',
+ option_based: false,
+ formattype: QuestionFormat.formattypes[:text_area]
+ }
+ end
+ def question_seed
+ {
+ text: 'how is our test coverage?',
+ default_value: 'Not as good as it could be.',
+ number: 1,
+ option_comment_display: true,
+ modifiable: true,
+ }
+ end
+ def annotation_seed
+ {
+ text: 'This is some test guidance for a customization',
+ type: Annotation.types[:guidance]
+ }
+ end
+ def question_option_seed
+ {
+ text: 'Option A',
+ number: 1,
+ is_default: true,
+ }
+ end
+ def plan_seed
+ {
+ title: 'Test plan',
+ funder_name: 'Organisation with a lot of funds',
+ grant_number: 'Grant123',
+ identifier: '123456789',
+ description: 'This is the project abstract.',
+ visibility: Plan.visibilities[:privately_visible],
+ principal_investigator: 'Jane Doe',
+ principal_investigator_identifier: 'ORCID123',
+ principal_investigator_email: 'jane.doe@pi.roadmap.org',
+ principal_investigator_phone: '1234',
+ data_contact: 'John Doe',
+ data_contact_email: 'john.doe@pi.roadmap.org',
+ data_contact_phone: '5678',
+ }
+ end
+ def theme_seed
+ {
+ title: 'Test theme',
+ description: 'This theme is used for testing',
+ locale: Language.find_by(abbreviation: FastGettext.locale),
+ }
+ end
+ def guidance_group_seed
+ {
+ name: 'Test guidance group',
+ optional_subset: false,
+ published: true,
+ }
+ end
+ def guidance_seed
+ {
+ text: 'This is thematic test guidance.',
+ published: true,
+ }
+ end
+
+ def validate_and_create_obj(obj)
+ obj.validate
+ if obj.errors.present?
+ # Unable to save the object, so output an error rather than burying it
+ puts "Unable to save #{obj.class.name} because: #{obj.errors.collect{ |e,m| "#{e}: #{m}" }.join(', ')}"
+ else
+ obj.save!
+ end
+ assert obj.valid?
+ obj
+ end
+
+ # Org initializers
+ def init_institution(**props)
+ validate_and_create_obj(Org.new(org_seed.merge(props)))
+ end
+ def init_funder(**props)
+ hash = { name: 'Test Funder', abbreviation: 'TSTFNDR', org_type: Org.org_type_values_for(:funder).min }
+ validate_and_create_obj(Org.new(org_seed.merge(hash.merge(props))))
+ end
+ def init_organisation(**props)
+ hash = { name: 'Test Organisation', abbreviation: 'TSTORG', org_type: Org.org_type_values_for(:organisation).min }
+ validate_and_create_obj(Org.new(org_seed.merge(hash.merge(props))))
+ end
+ def init_funder_organisation(**props)
+ hash = { name: 'Test Funder/Organisation', abbreviation: 'TSTFNDRORG', org_type: Org.org_type_values_for(:funder, :organisation).min }
+ validate_and_create_obj(Org.new(org_seed.merge(hash.merge(props))))
+ end
+
+ # User initializers
+ def init_researcher(org, **props)
+ validate_and_create_obj(User.new(user_seed.merge({
+ org: org,
+ surname: 'Researcher',
+ email: 'researcher@testing-roadmap.org',
+ }.merge(props))))
+ end
+ def init_org_admin(org, **props)
+ perms = Perm.where.not(name: ['admin', 'add_organisations',
+ 'change_org_affiliation', 'grant_api_to_orgs',
+ 'change_org_details'])
+ validate_and_create_obj(User.new(user_seed.merge({
+ org: org,
+ surname: 'OrgAdmin',
+ email: 'org.admin@testing-roadmap.org',
+ perms: perms,
+ }.merge(props))))
+ end
+ def init_super_admin(org, **props)
+ perms = Perm.all
+ validate_and_create_obj(User.new(user_seed.merge({
+ org: org,
+ surname: 'SuperAdmin',
+ email: 'super.admin@testing-roadmap.org',
+ perms: perms
+ }.merge(props))))
+ end
+
+ # Template initializers
+ def init_template(org, **props)
+ if org.is_a? Org
+ validate_and_create_obj(Template.new(template_seed.merge({ org: org }.merge(props))))
+ else
+ puts "You must supply an Org when creating a template! Got the following instead: #{org.inspect}"
+ nil
+ end
+ end
+ def init_phase(template, **props)
+ if template.is_a? Template
+ validate_and_create_obj(Phase.new(phase_seed.merge({ template: template }.merge(props))))
+ else
+ puts "You must supply a Template when creating a phase! Got the following instead: #{template.inspect}"
+ nil
+ end
+ end
+ def init_section(phase, **props)
+ if phase.is_a? Phase
+ validate_and_create_obj(Section.new(section_seed.merge({ phase: phase }.merge(props))))
+ else
+ puts "You must supply a Phase when creating a section! Got the following instead: #{phase.inspect}"
+ nil
+ end
+ end
+ def init_question_format(**props)
+ validate_and_create_obj(QuestionFormat.new(question_format_seed.merge(props)))
+ end
+ def init_question(section, **props)
+ if section.is_a? Section
+# TODO call init_question_format instead once the seeds.rb has been removed
+ props[:question_format] = QuestionFormat.first unless props[:question_format].present?
+ validate_and_create_obj(Question.new(question_seed.merge({ section: section }.merge(props))))
+ else
+ puts "You must supply a Section when creating a question! Got the following instead: #{section.inspect}"
+ nil
+ end
+ end
+ def init_annotation(org, question, **props)
+ if org.is_a?(Org) && question.is_a?(Question)
+ validate_and_create_obj(Annotation.new(annotation_seed.merge({ org: org, question: question }.merge(props))))
+ else
+ puts "You must supply an Org and Question when creating an annotation! Got the following instead: ORG - #{org.inspect}, QUESTION - #{question.inspect}"
+ nil
+ end
+ end
+ def init_question_option(question, **props)
+ if question.is_a?(Question)
+ validate_and_create_obj(QuestionOption.new(question_option_seed.merge({ question: question }.merge(props))))
+ else
+ puts "You must supply a Question when creating a question option! Got the following instead: QUESTION - #{question.inspect}"
+ nil
+ end
+ end
+ def init_theme(**props)
+ validate_and_create_obj(Theme.new(theme_seed.merge(props)))
+ end
+ def init_guidance_group(org, **props)
+ if org.is_a? Org
+ validate_and_create_obj(GuidanceGroup.new(guidance_group_seed.merge({ org: org }.merge(props))))
+ else
+ puts "You must supply an Org when creating a GuidanceGroup! Got the following instead: ORG: #{org.inspect}"
+ end
+ end
+ def init_guidance(guidance_group, **props)
+ if guidance_group.is_a?(GuidanceGroup)
+ validate_and_create_obj(Guidance.new(guidance_seed.merge({ guidance_group: guidance_group }.merge(props))))
+ else
+ puts "You must supply a GuidanceGroup when creating a Guidance! Got the following instead: GUIDANCE_GROUP: #{guidance_group.inspect}"
+ end
+ end
+ def init_plan(template, **props)
+ if template.is_a? Template
+ validate_and_create_obj(Plan.new(plan_seed.merge({ template: template }.merge(props))))
+ else
+ puts "You must supply a Template when creating a plan! Got the following instead: #{template.inspect}"
+ nil
+ end
+ end
+
+ # equality helpers for complex objects
+ def assert_annotations_equal(annotation1, annotation2)
+ assert_equal annotation1.text, annotation2.text, 'expected the annotations to have the same text'
+ assert_equal annotation1.type, annotation2.type, 'expected the annotations to be of the same type'
+ end
+ def assert_question_options_equal(option1, option2)
+ assert_equal option1.text, option2.text, 'expecetd the question options to have the same text'
+ assert_equal option1.number, option2.number, 'expecetd the question options to have the same number'
+ assert_equal option1.is_default, option2.is_default, 'expecetd the question options to have the same default flag value'
+ end
+ def assert_questions_equal(question1, question2)
+ assert_equal question1.number, question2.number, 'expected the question numbers to match'
+ assert_equal question1.text, question2.text, 'expected the question text to match'
+ assert_equal question1.question_format, question2.question_format, 'expected the question formats to match'
+ assert_equal question1.option_comment_display, question2.option_comment_display, 'expected the question optional comment display flags to match'
+ assert_equal question1.annotations.length, question2.annotations.length, 'expected the questions to have the same number of annotations'
+ assert_equal question1.question_options.length, question2.question_options.length, 'expected the questions to have the same number of options'
+ question1.annotations.each_with_index do |annotation, idx|
+ assert_annotations_equal(annotation, question2.annotations[idx])
+ end
+ question1.question_options.each_with_index do |option, idx|
+ assert_question_options_equal(option, question2.question_options[idx])
+ end
+ end
+ def assert_sections_equal(section1, section2)
+ assert_equal section1.number, section2.number, 'expected the section numbers to match'
+ assert_equal section1.title, section2.title, 'expected the section titles to match'
+ assert_equal section1.description, section2.description, 'expected the section descriptions to match'
+ assert_equal section1.questions.length, section2.questions.length, 'expected the sections to have the same number of questions'
+ section1.questions.each_with_index do |question, idx|
+ assert_questions_equal(question, section2.questions[idx])
+ end
+ end
+ def assert_phases_equal(phase1, phase2)
+ assert_equal phase1.number, phase2.number, 'expected the phase numbers to match'
+ assert_equal phase1.title, phase2.title, 'expected the phase titles to match'
+ assert_equal phase1.description, phase2.description, 'expected the phase descriptions to match'
+ assert_equal phase1.sections.length, phase2.sections.length, 'expected the phase to have the same number of sections'
+ phase1.sections.each_with_index do |section, idx|
+ assert_sections_equal(section, phase2.sections[idx])
+ end
+ end
+
+
# Get the organisational admin for the Org specified or create one
# ----------------------------------------------------------------------
def scaffold_org_admin(org)
@@ -52,7 +349,7 @@
template = Template.new(title: 'Test template',
description: 'My test template',
links: {"funder":[],"sample_plan":[]},
- org: Org.first, migrated: false, dmptemplate_id: "0000009999")
+ org: Org.first, archived: false, family_id: "0000009999")
template.phases << Phase.new(title: 'Test phase',
description: 'My test phase',
@@ -87,7 +384,7 @@
# Version the template
# ----------------------------------------------------------------------
def version_the_template
- @template = @template.get_new_version
+ @template = @template.generate_version!
end
# Scaffold a new Plan based on the scaffolded Template
@@ -148,11 +445,33 @@
if exclusions.include?(name)
assert_not_equal object.send(name), copy.send(name), "expected the deep_copy of #{object.class.name}.#{name} to be unique in the copy"
else
- assert_equal object.send(name), copy.send(name), "expected the deep_copy of #{object.class.name}.#{name} to match"
+ unless object.send(name).nil? || copy.send(name)
+ assert_equal object.send(name), copy.send(name), "expected the deep_copy of #{object.class.name}.#{name} to match"
+ end
end
end
end
+ def assert_deep_copy(original, copy, **options)
+ if original.class == copy.class
+ relations = options.fetch(:relations, []).map(&:to_sym)
+ assert(original.object_id != copy.object_id)
+ assert_nil(copy.id, "id should be nil for #{copy.class}") if copy.respond_to?(:id)
+ assert_nil(copy.created_at, "created_at should be nil for #{copy.class}") if copy.respond_to?(:created_at)
+ assert_nil(copy.updated_at, "updated_at should be nil for #{copy.class}") if copy.respond_to?(:updated_at)
+ relations.each do |relation|
+ if copy.respond_to?(relation)
+ relation_obj = copy.send(relation)
+ if relation_obj.respond_to?(:each)
+ relation_obj.each do |obj|
+ assert_nil(obj.id, "id should be nil for the relation object from #{obj.class}") if copy.respond_to?(:id)
+ end
+ end
+ end
+ end
+ end
+ end
+
# ----------------------------------------------------------------------
def verify_has_many_relationship(object, new_association, initial_expected_count)
# Assumes that the association name matches the pluralized name of the class
diff --git a/test/unit/answer_test.rb b/test/unit/answer_test.rb
index aa4ef95..04cf539 100644
--- a/test/unit/answer_test.rb
+++ b/test/unit/answer_test.rb
@@ -35,7 +35,7 @@
assert_not q.nil?, "expected the test template to have a question of type: #{qf.title}"
answr = Answer.create(user: @user, plan: @plan, question: q, question_options: [q.question_options.first])
- assert_not answr.id.nil?, "was expecting to be able to create a new Answer for a #{qf.title} question: #{answr.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}"
+ assert_not_nil answr.id, "was expecting to be able to create a new Answer for a #{qf.title} question: #{answr.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}"
answr.question_options = [q.question_options.last]
answr.save!
@@ -52,15 +52,16 @@
qf = QuestionFormat.where(option_based: true).first
q = @plan.template.questions.select{|q| q.question_format == qf }.first
- assert_not q.nil?, "expected the test template to have a question of type: #{qf.title}"
+ assert_not_nil q, "expected the test template to have a question of type: #{qf.title}"
answr = Answer.create(user: @user, plan: @plan, question: q, question_options: [q.question_options.first])
copy = Answer.deep_copy(answr)
-
- assert_equal answr.text, copy.text, "expected the answer text to be the same"
- assert_equal answr.question.id, copy.question.id, "expected the question to be the same"
- answr.question_options.each do |opt|
- assert copy.question_options.include?(opt), "expected the copy to have question options"
+ unless answr.text.nil? || copy.text.nil?
+ assert_equal answr.text, copy.text, "expected the answer text to be the same"
+ assert_equal answr.question.id, copy.question.id, "expected the question to be the same"
+ answr.question_options.each do |opt|
+ assert copy.question_options.include?(opt), "expected the copy to have question options"
+ end
end
end
diff --git a/test/unit/concerns/versionable_test.rb b/test/unit/concerns/versionable_test.rb
new file mode 100644
index 0000000..60391ec
--- /dev/null
+++ b/test/unit/concerns/versionable_test.rb
@@ -0,0 +1,257 @@
+require 'test_helper'
+
+class VersionableTest < ActiveSupport::TestCase
+ include Versionable
+
+ setup do
+ @template = create_template
+ end
+ def create_template
+ funder = init_funder
+ template = init_template(funder)
+ phase = init_phase(template)
+ section = init_section(phase)
+ question = init_question(section)
+ init_annotation(funder, question)
+ return template
+ end
+ test "versionable concern is included" do
+ assert(self.respond_to?(:get_modifiable))
+ end
+ test "#find_in_space raises ArgumentError when search_scape does not respond_to to each" do
+ exception = assert_raises(ArgumentError) do
+ find_in_space(nil, nil)
+ end
+ assert_equal(_('The search_space does not respond to each'), exception.message)
+ end
+ test "#find_in_space raises ArgumentError when search_scape does not have elements" do
+ exception = assert_raises(ArgumentError) do
+ find_in_space(nil, [])
+ end
+ assert_equal(_('The search space does not have elements associated'), exception.message)
+ end
+ test "#find_in_space looks for the object in the search_scape that has elements of its same class" do
+ # Looking for phase
+ phase = init_phase(@template)
+ assert_equal(@template.phases.first, find_in_space(phase, @template.phases), 'phase found in the space')
+ phase.number = 2
+ assert_not(find_in_space(phase, @template.phases), 'phase not found in the space')
+ # Looking for section
+ section = init_section(Phase.new)
+ assert_equal(@template.phases.first.sections.first,
+ find_in_space(section, @template.phases.first.sections),
+ 'section found in the space')
+ section.number = 2
+ assert_not(find_in_space(section, @template.phases.first.sections), 'section not found in the space')
+ # Looking for a question
+ question = init_question(Section.new)
+ assert_equal(@template.phases.first.sections.first.questions.first,
+ find_in_space(question, @template.phases.first.sections.first.questions),
+ ' question found in the space')
+ question.number = 2
+ assert_not(find_in_space(question, @template.phases.first.sections.first.questions), 'question not found in the space')
+ # Looking for an annotation
+ annotation = init_annotation(@template.org, Question.new)
+ assert_equal(@template.phases.first.sections.first.questions.first.annotations.first,
+ find_in_space(annotation, @template.phases.first.sections.first.questions.first.annotations), 'annotation found in the space')
+ annotation.text = 'foo'
+ assert_not(find_in_space(annotation, @template.phases.first.sections.first.questions.first.annotations))
+ # Looking for something else
+ assert_not(find_in_space({}, [{}]))
+ end
+ test "#find_in_space looks for the object in the relation" do
+ # Looking for section
+ section = init_section(@template.phases.first)
+ assert_equal(@template.phases.first.sections.first,
+ find_in_space(section, @template.phases), 'section found in the space through its phase number')
+ # Looking for question
+ question = init_question(@template.phases.first.sections.first)
+ assert_equal(@template.phases.first.sections.first.questions.first,
+ find_in_space(question, @template.phases), 'question found in the space through its phase/section number')
+ # Looking for annotation
+ annotation = init_annotation(@template.org, @template.phases.first.sections.first.questions.first)
+ assert_equal(@template.phases.first.sections.first.questions.first.annotations.first,
+ find_in_space(annotation, @template.phases), 'annotation found int the space through its phase/section/question number')
+ # Looking for a question in a not known search_space
+ assert_not(find_in_space(Question.new, [{}]))
+ end
+ test "#find_in_space looks for an object that does not belong to the hierarchy" do
+ question = init_question(@template.phases.first.sections.first)
+ question.phase.number = 2
+ assert_not(find_in_space(question, @template.phases))
+ end
+
+ test "#get_new raises ArgumentError unless the object respond_to template" do
+ exception = assert_raises(ArgumentError) do
+ get_new(@template)
+ end
+ assert_equal(_('obj should be a Phase, Section, Question, or Annotation'), exception.message)
+ end
+
+ test "#get_new raises RuntimeError when template is not latest" do
+ @template.published = true
+ @template.generate_version!
+
+ hierarchy_objects = [
+ Phase.new(template_id: @template.id),
+ Section.new(phase_id: @template.phases.first.id),
+ Question.new(section_id: @template.phases.first.sections.first.id),
+ Annotation.new(question_id: @template.phases.first.sections.first.questions.first.id)
+ ]
+
+ hierarchy_objects.each do |obj|
+ exception = assert_raises(RuntimeError) do
+ get_new(obj)
+ end
+ assert_equal(_('A historical template cannot be retrieved for being modified'), exception.message)
+ end
+ end
+
+ test "#get_new returns same object when template is not published" do
+ # Looking for phase
+ phase = Phase.new(template: @template)
+ new_phase = get_new(phase)
+ assert_equal(phase.template_id, new_phase.template_id, 'returns the phase without generating a new template hierarchy')
+ # Looking for section
+ section = Section.new(phase: @template.phases.first)
+ new_section = get_new(section)
+ assert_equal(section.phase_id, new_section.phase_id, 'returns the section without generating a new template hierarchy')
+ # Looking for question
+ question = Question.new(section: @template.phases.first.sections.first)
+ new_question = get_new(question)
+ assert_equal(question.section_id, new_question.section_id, 'returns the question without generating a new template hierarchy')
+ # Looking for annotation fails
+ annotation = Annotation.new(question: @template.phases.first.sections.first.questions.first)
+ new_annotation = get_new(annotation)
+ assert_equal(annotation.question_id, new_annotation.question_id, 'returns the same annotation without generating a new template hierarchy')
+ end
+
+ test "#get_new returns new phase when template is published" do
+ @template.published = true
+ @template.save!
+ phase = Phase.new(template: @template)
+ new_phase = get_new(phase)
+ assert_not_equal(phase.template_id, new_phase.template_id)
+ end
+
+ test "#get_new returns new section when template is published" do
+ @template.published = true
+ @template.save!
+ section = Section.new(phase: @template.phases.first)
+ new_section = get_new(section)
+ assert_not_equal(section.phase_id, new_section.phase_id)
+ end
+
+ test "#get_new returns new question when template is published" do
+ @template.published = true
+ @template.save!
+ question = Question.new(section: @template.phases.first.sections.first)
+ new_question = get_new(question)
+ assert_not_equal(question.section_id, new_question.section_id)
+ end
+
+ test "#get_new returns new annotation when template is published" do
+ @template.published = true
+ @template.save!
+ annotation = Annotation.new(question: @template.phases.first.sections.first.questions.first)
+ new_annotation = get_new(annotation)
+ assert_not_equal(annotation.question_id, new_annotation.question_id)
+ end
+
+ test "#get_modifiable raises ArgumentError when the object is not template or object responding to template" do
+ exception = assert_raises(ArgumentError) do
+ get_modifiable({})
+ end
+ assert_equal(_('obj should be a Template, Phase, Section, Question, or Annotation'), exception.message)
+ end
+
+ test "#get_modifiable raises RuntimeError when template is not latest" do
+ @template.published = true
+ @template.generate_version!
+
+ hierarchy_objects = [
+ @template.phases.first,
+ @template.phases.first.sections.first,
+ @template.phases.first.sections.first.questions.first,
+ @template.phases.first.sections.first.questions.first.annotations.first
+ ]
+
+ hierarchy_objects.each do |obj|
+ exception = assert_raises(RuntimeError) do
+ get_modifiable(obj)
+ end
+ assert_equal(_('A historical template cannot be retrieved for being modified'), exception.message)
+ end
+ end
+
+ test "#get_modifiable returns same object when template is not published" do
+ # Looking for phase
+ phase = @template.phases.first
+ new_phase = get_modifiable(phase)
+ assert_equal(phase.id, new_phase.id, 'returns the same phase id')
+ assert_equal(phase.template_id, new_phase.template_id, 'returns the phase without generating a new template hierarchy')
+ # Looking for section
+ section = @template.phases.first.sections.first
+ new_section = get_modifiable(section)
+ assert_equal(section.id, new_section.id, 'returns the same section id')
+ assert_equal(section.phase.template, new_section.phase.template, 'returns the section without generating a new template hierarchy')
+ # Looking for a question
+ question = @template.phases.first.sections.first.questions.first
+ new_question = get_modifiable(question)
+ assert_equal(question.id, new_question.id, 'returns the same question id')
+ assert_equal(question.section.phase.template, new_question.section.phase.template, 'returns the question without generating a new template hierarchy')
+ # Looking for an annotation
+ annotation = @template.phases.first.sections.first.questions.first.annotations.first
+ new_annotation = get_modifiable(annotation)
+ assert_equal(annotation.id, new_annotation.id, 'returns the same annotation id')
+ assert_equal(annotation.question.section.phase.template, new_annotation.question.section.phase.template, 'returns the annotation without generating a new template hierarchy')
+ end
+
+ test "#get_modifiable returns new phase when template is published" do
+ @template.published = true
+ @template.save!
+ phase = @template.phases.first
+ new_phase = get_modifiable(phase)
+ assert_not_equal(phase.id, new_phase.id, 'returns different phase id')
+ assert_not_equal(phase.template_id, new_phase.template_id, 'returns different template belonging')
+ end
+
+ test "#get_modifiable returns new section when template is published" do
+ @template.published = true
+ @template.save!
+ section = @template.phases.first.sections.first
+ new_section = get_modifiable(section)
+ assert_not_equal(section.id, new_section.id, 'returns different section id')
+ assert_not_equal(section.phase.template, new_section.phase.template, 'returns different template belonging')
+ end
+
+ test "#get_modifiable returns new question when template is published" do
+ @template.published = true
+ @template.save!
+ question = @template.phases.first.sections.first.questions.first
+ new_question = get_modifiable(question)
+ assert_not_equal(question.id, new_question.id, 'returns different question id')
+ assert_not_equal(question.section.phase.template, new_question.section.phase.template, 'returns different template belonging')
+ end
+
+ test "#get_modifiable returns new annotation when template is published" do
+ @template.published = true
+ @template.save!
+ annotation = @template.phases.first.sections.first.questions.first.annotations.first
+ new_annotation = get_modifiable(annotation)
+ assert_not_equal(annotation.id, new_annotation.id, 'returns different annotation id')
+ assert_not_equal(annotation.question.section.phase.template, new_annotation.question.section.phase.template, 'returns different template belonging')
+ end
+
+ test "#get_modifiable returns new question_option when template is published" do
+ @template.published = true
+ @template.save!
+ question = @template.phases.first.sections.first.questions.first
+ question.question_options << init_question_option(question)
+ question_option = question.question_options.first
+ new_question = get_modifiable(question)
+ new_question_option = new_question.question_options.first
+ assert_not_equal(question_option.id, new_question_option.id, 'returns different question_option id')
+ assert_not_equal(question_option.question.section.phase.template, new_question_option.question.section.phase.template, 'returns different template belonging')
+ end
+end
\ No newline at end of file
diff --git a/test/unit/notification_test.rb b/test/unit/notification_test.rb
new file mode 100644
index 0000000..7be2e1b
--- /dev/null
+++ b/test/unit/notification_test.rb
@@ -0,0 +1,52 @@
+require 'test_helper'
+
+class NotificationTest < ActiveSupport::TestCase
+
+ setup do
+ @super_admin = User.find_by(email: 'super_admin@example.com')
+
+ @notification = Notification.create!(
+ notification_type: Notification.notification_types[:global],
+ title: 'notification_1',
+ level: Notification.levels[:info],
+ body: 'notification 1',
+ dismissable: true,
+ starts_at: Time.now,
+ expires_at: Time.now + 1.days)
+ end
+
+ # Validity
+ test 'validations valid' do
+ 1.upto(10) { |i| assert(@notification.valid?) }
+ end
+
+ # Date validation
+ test 'validations inconsistent dates' do
+ @notification.expires_at = Date.today - 1.days
+ assert_not(@notification.valid?)
+ end
+
+ # Missing parameters
+ test 'validations missing params' do
+ @notification.dismissable = nil
+ assert(@notification.valid?)
+ @notification.dismissable = false
+ @notification.notification_type = nil
+ assert_not(@notification.valid?)
+ @notification.notification_type = Notification.notification_types[:global]
+ @notification.title = nil
+ assert_not(@notification.valid?)
+ @notification.title = "Testing"
+ @notification.body = nil
+ assert_not(@notification.valid?)
+ @notification.body = "Testing"
+ @notification.level = nil
+ assert_not(@notification.valid?)
+ @notification.level = Notification.levels[:info]
+ @notification.starts_at = nil
+ assert_not(@notification.valid?)
+ @notification.starts_at = Time.now
+ @notification.expires_at = nil
+ assert_not(@notification.valid?)
+ end
+end
diff --git a/test/unit/org_test.rb b/test/unit/org_test.rb
index 0d5e284..645948a 100644
--- a/test/unit/org_test.rb
+++ b/test/unit/org_test.rb
@@ -153,7 +153,7 @@
end
# ---------------------------------------------------
- test "can manage has_many relationship with Dmptemplates" do
+ test "can manage has_many relationship with Templates" do
tmplt = Template.new(title: 'Added through test', version: 1)
verify_has_many_relationship(@org, tmplt, @org.templates.count)
end
diff --git a/test/unit/perm_test.rb b/test/unit/perm_test.rb
index a40c704..a651315 100644
--- a/test/unit/perm_test.rb
+++ b/test/unit/perm_test.rb
@@ -1,7 +1,6 @@
require 'test_helper'
class PermTest < ActiveSupport::TestCase
-
setup do
@user = User.last
diff --git a/test/unit/phase_test.rb b/test/unit/phase_test.rb
index 14ef133..5383b59 100644
--- a/test/unit/phase_test.rb
+++ b/test/unit/phase_test.rb
@@ -3,60 +3,60 @@
class PhaseTest < ActiveSupport::TestCase
setup do
- @org = Org.first
- @template = Template.first
- @phase = Phase.create(title: 'Test Phase 1', number: 1, template: @template)
+ # Need to clear the tables until we get seed.rb out of test_helper.rb
+ Template.delete_all
+ @funder = init_funder
+ @template = init_template(@funder, published: true)
+ @phase = init_phase(@template)
end
- # ---------------------------------------------------
test "required fields are required" do
assert_not Phase.new.valid?
- assert_not Phase.new(title: 'Testing', number: 1).valid?, "expected the dmptemplate field to be required"
+ assert_not Phase.new(title: 'Testing', number: 1).valid?, "expected the template field to be required"
assert_not Phase.new(number: 2, template: @template).valid?, "expected the title field to be required"
assert_not Phase.new(title: 'Testing', template: @template).valid?, "expected the number field to be required"
- # Ensure the bar minimum and complete versions are valid
+ # Ensure the bare minimum and complete versions are valid
a = Phase.new(title: 'Testing', template: @template, number: 2)
assert a.valid?, "expected the 'title', 'number' and 'template' fields to be enough to create an Phase! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}"
end
- # ---------------------------------------------------
- test "to_s returns the title" do
- assert_equal @phase.title, @phase.to_s
+ test "titles scope returns a list of all phase id with their titles for the specified template" do
+ init_phase(@template, { title: 'test scope 1', number: 2 })
+ init_phase(@template, { title: 'test scope 2', number: 3 })
+ titles = Phase.titles(@template)
+ assert_equal 3, titles.length, 'expected 3 phases, the orignal and 2 new'
+ assert_not titles.select{ |p| p.title == 'test scope 2' }.empty?, "expected to find the second phase"
end
- # ---------------------------------------------------
- test "has_sections returns false if there are NO published versions with sections" do
- # TODO: build out this test if the has_sections method is actually necessary
+ test "titles scope does not return phases from other templates" do
+ init_phase(@template, { title: 'test scope 1', number: 2 })
+ template2 = init_template(@funder, { title: 'template 2' })
+ init_phase(template2, { title: 'other template scope' })
+ titles = Phase.titles(@template)
+ assert titles.select{ |p| p.title == 'other template scope' }.empty?, "expected to not find the other template's phase"
end
- # ---------------------------------------------------
- test "deep copy" do
- verify_deep_copy(@phase, ['id', 'created_at', 'updated_at'])
- end
-
- # ---------------------------------------------------
- test "can CRUD Phase" do
- obj = Phase.create(title: 'Testing CRUD', template: @template, number: 4)
- assert_not obj.id.nil?, "was expecting to be able to create a new Phase! - #{obj.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}"
-
- obj.title = 'Testing an update'
- obj.save!
- obj.reload
- assert_equal 'Testing an update', obj.title, "Was expecting to be able to update the title of the Phase!"
-
- assert obj.destroy!, "Was unable to delete the Phase!"
- end
-
- # ---------------------------------------------------
- test "can manage has_many relationship with Sections" do
- s = Section.new(title: 'Test Section', number: 2)
- verify_has_many_relationship(@phase, s, @phase.sections.count)
+ test "#deep_copy creates a new phase object and attaches new section objects" do
+ assert_deep_copy(@phase, @phase.deep_copy, relations: [:sections])
end
- # ---------------------------------------------------
- test "can manage belongs_to relationship with Template" do
- phase = Phase.new(title: 'Tester', number: 9)
- verify_belongs_to_relationship(phase, @template)
+ test "num_questions returns the total number of questions for the phase" do
+ section = init_section(@phase)
+ section2 = init_section(@phase, { title: 'Section B', number: 2 })
+ init_question(section)
+ init_question(section, { text: 'Question number 2', number: 2 })
+ init_question(section2)
+ assert_equal 3, @phase.num_questions, 'expected 3 questions for the phase, 2 for the 1st section and 1 for the 2nd section'
+ end
+
+ test "num_questions does not count questions that belong to other templates" do
+ section = init_section(@phase)
+ init_question(section)
+ template2 = init_template(@funder, { title: 'template 2' })
+ phase2 = init_phase(template2, { title: 'other template scope' })
+ section2 = init_section(phase2)
+ init_question(section2)
+ assert_equal 1, @phase.num_questions, 'expected 1 question for the phase'
end
end
diff --git a/test/unit/plan_test.rb b/test/unit/plan_test.rb
index 1099e63..9aec140 100644
--- a/test/unit/plan_test.rb
+++ b/test/unit/plan_test.rb
@@ -42,10 +42,6 @@
=end
end
- # ---------------------------------------------------
- test "dmptemplate returns the template" do
- assert_equal @plan.template, @plan.dmptemplate
- end
# ---------------------------------------------------
test "correctly creates a new answer" do
@@ -54,8 +50,10 @@
q.save!
answer = @plan.answer(q.id)
- assert_equal nil, answer.id, "expected a new Answer"
- assert_equal q.default_value, answer.text, "expected the new Answer to use the Default Answer for the Question"
+ assert_nil answer.id, "expected a new Answer"
+ unless q.default_value.nil?
+ assert_equal q.default_value, answer.text, "expected the new Answer to use the Default Answer for the Question"
+ end
end
# ---------------------------------------------------
diff --git a/test/unit/question_test.rb b/test/unit/question_test.rb
index 706a10d..c6b3066 100644
--- a/test/unit/question_test.rb
+++ b/test/unit/question_test.rb
@@ -3,120 +3,79 @@
class QuestionTest < ActiveSupport::TestCase
setup do
- @user = User.last
-
- scaffold_template
-
- @section = @template.phases.first.sections.first
-
- @question = Question.create(text: 'Test question', default_value: 'ABCD',
- number: 999, section: @section,
- question_format: QuestionFormat.where(option_based: false).first,
- option_comment_display: true, modifiable: true,
- themes: [Theme.first],
- annotations: [Annotation.new(org: @user.org,
- text: "just a suggestion")])
+ # Need to clear the tables until we get seed.rb out of test_helper.rb
+ Template.delete_all
+ @funder = init_funder
+ @institution = init_institution
+ @template = init_template(@institution, published: true)
+ @phase = init_phase(@template)
+ @section = init_section(@phase)
+ @question = init_question(@section)
end
- # ---------------------------------------------------
test "required fields are required" do
assert_not Question.new.valid?
assert_not Question.new(section: @section, number: 7).valid?, "expected the 'text' field to be required"
assert_not Question.new(number: 7, text: 'Testing').valid?, "expected the 'section' field to be required"
assert_not Question.new(section: @section, text: 'Testing').valid?, "expected the 'number' field to be required"
- # Ensure the bar minimum and complete versions are valid
+ # Ensure the bare minimum and complete versions are valid
a = Question.new(section: @section, text: 'Testing', number: 7)
assert a.valid?, "expected the 'text', 'section' and 'number' fields to be enough to create an Question! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}"
end
- # ---------------------------------------------------
test "to_s returns the Question text" do
assert_equal @question.text, @question.to_s
end
- # ---------------------------------------------------
+ test "option_based? returns the correct boolean value" do
+ assert_not @question.option_based?
+# TODO: replace with a call to the init_question_format factory method once seeds.rb is no longer being loaded
+ @question.question_format = QuestionFormat.find_by(option_based: true)
+ @question.save!
+ assert @question.option_based?
+ end
+
+ test "#deep_copy creates a new question object and attaches new annotations/question_options objects" do
+ init_annotation(@institution, @question)
+ init_question_option(@question)
+ assert_deep_copy(@question, @question.deep_copy, relations: [:annotations, :question_options])
+ end
+
+# TODO: This method should get moved to a view helper instead
test "returns the correct themed guidance for the org" do
- all = Theme.first.guidances + Theme.last.guidances
+ theme = init_theme
+ guidance_group = init_guidance_group(@institution)
+ funder_guidance_group = init_guidance_group(@funder, { title: 'Test funder guidance group' } )
+ guidance = init_guidance(guidance_group, { themes: [theme] })
+ funder_guidance = init_guidance(funder_guidance_group, { themes: [theme] })
- # Attach 2 themes to the question
- @question.themes = [Theme.first, Theme.last]
+ @question.themes << theme
@question.save!
- # Attach the first theme's first gudiance's group to the org
- @user.org.guidance_groups << Theme.first.guidances.first.guidance_group
- @user.save!
+ institution_guidances = @question.guidance_for_org(@institution)
+ # method retuns a hash {'descriptive string': 'guidances array'}
+ assert_equal 1, institution_guidances.length
+ assert_equal guidance, institution_guidances.first.last
- assert_not @question.guidance_for_org(@user.org).empty?, "expected guidance to be returned"
-
- assert @question.guidance_for_org(@user.org).first.first.include?(Theme.first.title), "expected the theme.title"
- assert @question.guidance_for_org(@user.org).first.first.include?(Theme.first.guidances.first.guidance_group.name), "expected the guidance_group.name"
- assert_equal Theme.first.guidances.first, @question.guidance_for_org(@user.org).first.last, "expected the guidance object to be returned"
+ funder_guidances = @question.guidance_for_org(@funder)
+ # method retuns a hash {'descriptive string', 'guidances array'}
+ assert_equal 1, funder_guidances.length
+ assert_equal funder_guidance, funder_guidances.first.last
end
-
+
# ---------------------------------------------------
test "returns the correct annotation for the org" do
- @question.annotations = [Annotation.create(org: @user.org, text: 'Test 1', type: Annotation.types[:example_answer]),
- Annotation.create(org: Org.first, text: 'Test 2', type: Annotation.types[:example_answer])]
- @question.save!
-
- assert_equal 'Test 1', @question.annotations.where(org_id: @user.org.id).first.text, "expected the correct annotation"
- assert_equal 'Test 2', @question.annotations.where(org_id: Org.first.id).first.text, "expected the correct annotation"
-
- org = Org.create(name: 'New One', links: {"org":[]})
- assert_equal 0, @question.get_example_answers(org.id).length, "expected no annotation for a new org"
- end
-
- # ---------------------------------------------------
- test "deep copy" do
- verify_deep_copy(@question, ['id', 'created_at', 'updated_at'])
- end
-
- # ---------------------------------------------------
- test "can CRUD Question" do
- obj = Question.create(section: @section, text: 'Test ABC', number: 7)
- assert_not obj.id.nil?, "was expecting to be able to create a new Question: #{obj.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}"
-
- obj.text = 'Testing an update'
- obj.save!
- obj.reload
- assert_equal 'Testing an update', obj.text, "Was expecting to be able to update the text of the Question!"
-
- assert obj.destroy!, "Was unable to delete the Question!"
- end
-
- # ---------------------------------------------------
- test "can manage belongs_to relationship with Section" do
- verify_belongs_to_relationship(@question, @template.phases.first.sections.last)
- end
-
- # ---------------------------------------------------
- test "can manage belongs_to relationship with QuestionFormat" do
- verify_belongs_to_relationship(@question, QuestionFormat.where(option_based: false).last)
- end
-
- # ---------------------------------------------------
- test "can manage has_many relationship with Answer" do
- scaffold_plan
- a = Answer.new(user: @user, plan: @plan, text: 'Test Answer')
- verify_has_many_relationship(@question, a, @question.answers.count)
- end
-
- # ---------------------------------------------------
- test "can manage has_many relationship with QuestionOption" do
- qo = QuestionOption.new(text: 'Test', number: 9)
- verify_has_many_relationship(@question, qo, @question.question_options.count)
- end
-
- # ---------------------------------------------------
- test "can manage has_many relationship with Annotation" do
- sa = Annotation.new(text: 'Suggested Answer', org: @user.org)
- verify_has_many_relationship(@question, sa, @question.annotations.count)
- end
-
- # ---------------------------------------------------
- test "can manage has_many relationship with Themes" do
- t = Theme.new(title: 'Test Theme')
- verify_has_many_relationship(@question, t, @question.themes.count)
+ annotation = init_annotation(@institution, @question, { type: Annotation.types[:example_answer] })
+ annotation2 = init_annotation(@institution, @question)
+ funder_annotation = init_annotation(@funder, @question, { text: 'Test funder example answer', type: Annotation.types[:example_answer] } )
+ funder_annotation2 = init_annotation(@funder, @question, { text: 'Test funder guidance'} )
+
+ institutional_annotations = @question.get_example_answers(@institution)
+ assert_equal 1, institutional_annotations.length
+ assert_equal annotation, institutional_annotations.first
+ funder_annotations = @question.get_example_answers(@funder)
+ assert_equal 1, funder_annotations.length
+ assert_equal funder_annotation, funder_annotations.first
end
end
diff --git a/test/unit/section_test.rb b/test/unit/section_test.rb
index 5a22b5f..b14d556 100644
--- a/test/unit/section_test.rb
+++ b/test/unit/section_test.rb
@@ -3,56 +3,34 @@
class SectionTest < ActiveSupport::TestCase
setup do
- scaffold_template
-
- @section = Section.create(title: 'Test Section', description: 'My test section', number: 99,
- published: true, phase: @template.phases.first, modifiable: false)
+ # Need to clear the tables until we get seed.rb out of test_helper.rb
+ Template.delete_all
+ funder = init_funder
+ template = init_template(funder, published: true)
+ @phase = init_phase(template)
+ @section = init_section(@phase)
end
- # ---------------------------------------------------
test "required fields are required" do
assert_not Section.new.valid?
- assert_not Section.new(phase: @template.phases.last, number: 9).valid?, "expected the 'title' field to be required"
+ assert_not Section.new(phase: @phase, number: 9).valid?, "expected the 'title' field to be required"
assert_not Section.new(title: 'Tester', number: 9).valid?, "expected the 'phase' field to be required"
- assert_not Section.new(phase: @template.phases.last, title: 'Tester').valid?, "expected the 'number' field to be required"
+ assert_not Section.new(phase: @phase, title: 'Tester').valid?, "expected the 'number' field to be required"
# Ensure the bare minimum and complete versions are valid
- a = Section.new(phase: @template.phases.last, title: 'Tester', number: 9)
+ a = Section.new(phase: @phase, title: 'Tester', number: 9)
assert a.valid?, "expected the 'phase', 'title' and 'number' fields to be enough to create an Section! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}"
end
- # ---------------------------------------------------
test "to_s returns the title" do
assert_equal @section.title, @section.to_s
end
- # ---------------------------------------------------
- test "deep copy" do
- verify_deep_copy(@section, ['id', 'created_at', 'updated_at'])
+ test "#deep_copy creates a new section object and attaches new question objects" do
+ assert_deep_copy(@section, @section.deep_copy, relations: [:questions])
end
-
- # ---------------------------------------------------
- test "can CRUD Section" do
- obj = Section.create(phase: @template.phases.last, title: 'Tester', number: 9)
- assert_not obj.id.nil?, "was expecting to be able to create a new Section: #{obj.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}"
- obj.description = 'my tester'
- obj.save!
- obj.reload
- assert_equal 'my tester', obj.description, "Was expecting to be able to update the description of the Section!"
-
- assert obj.destroy!, "Was unable to delete the Section!"
- end
-
- # ---------------------------------------------------
- test "can manage belongs_to relationship with Phase" do
- section = Section.new(title: 'Tester', number: 99)
- verify_belongs_to_relationship(section, @template.phases.first)
- end
-
- # ---------------------------------------------------
- test "can manage has_many relationship with Question" do
- question = Question.new(text: 'Testing', number: 1)
- verify_has_many_relationship(@section, question, @section.questions.count)
+ test "default values are properly set on section creation" do
+ assert(@section.modifiable, 'expected a new section to be modifiable')
end
end
\ No newline at end of file
diff --git a/test/unit/template_test.rb b/test/unit/template_test.rb
index 392a847..78401f0 100644
--- a/test/unit/template_test.rb
+++ b/test/unit/template_test.rb
@@ -3,9 +3,22 @@
class TemplateTest < ActiveSupport::TestCase
setup do
- @org = Org.last
+ # Need to clear the tables until we get seed.rb out of test_helper.rb
+ Template.destroy_all
- scaffold_template
+ @funder = init_funder
+ @org = init_organisation
+ @institution = init_institution
+ @funder_org = init_funder_organisation
+
+ @basic_template = init_template(@funder, published: true)
+ end
+
+ def init_full_template(template)
+ phase = init_phase(template)
+ section = init_section(phase)
+ init_question(section)
+ return template
end
def settings(extras = {})
@@ -18,159 +31,397 @@
def default_formatting
Settings::Template::DEFAULT_SETTINGS[:formatting]
end
+
+ test "default values are properly set on template creation" do
+ template = init_template(@funder)
+ assert_equal false, template.published, 'expected a new template to not be published'
+ assert_equal false, template.archived, 'expected a new template to not be archived'
+ assert_not_nil template.family_id, 'expected a new template to have a family_id'
+ assert_equal false, template.is_default, 'expected a new template to not be the default template'
+ assert template.publicly_visible?, 'expected a new funder template to be publicly visible'
- # ---------------------------------------------------
+ tmplt = init_template(@org)
+ tmplt2 = init_template(@funder_org)
+ assert tmplt.organisationally_visible?, 'expected a new non-funder template to be organisationally visible'
+ assert tmplt2.organisationally_visible?, 'expected a new non-funder template to be organisationally visible'
+ end
+
test "required fields are required" do
assert_not Template.new.valid?
assert_not Template.new(version: 1, title: 'Tester').valid?, "expected the 'org' field to be required"
- assert_not Template.new(org: @org, version: 1).valid?, "expected the 'title' field to be required"
-
- # Ensure the bare minimum and complete versions are valid
- a = Template.new(org: @org, title: 'Tester')
- assert a.valid?, "expected the 'org', 'version' and 'title' fields to be enough to create an Template! - #{a.errors.map{|f, m| f.to_s + ' ' + m}.join(', ')}"
+ assert_not Template.new(org: @funder, version: 1).valid?, "expected the 'title' field to be required"
end
- # ---------------------------------------------------
- test "family_ids scope only returns the dmptemplate_ids for the specific Org" do
- Org.all.each do |org|
- family_ids = Template.valid.all.pluck(:dmptemplate_id).uniq
- scoped = Template.dmptemplate_ids
- assert_equal family_ids.count, scoped.count
-
- family_ids.each do |id|
- assert scoped.include?(id), "expected the family_ids scope to contain #{id} for Org: #{org.id}"
- end
- scoped.each do |id|
- assert family_ids.include?(id), "expected #{id} to be a valid dmptemplate_id for Org: #{org.id}"
- end
+ test "unarchived returns only unarchived templates" do
+ # Create an unarchived and an archived template (set archived after init because it will default to false on creation)
+ archived = init_template(@funder, { title: 'Archived Template' })
+ archived.update_attributes(archived: true)
+ results = Template.unarchived
+ assert_equal 1, results.length, 'expected there to be only 1 unarchived template'
+ assert_equal @basic_template, results.first, 'expected the correct template to have been returned'
+ end
+
+ test "archived returns only archived templates" do
+ # Create an unarchived and an archived template (set archived after init because it will default to false on creation)
+ archived = init_template(@funder, { title: 'Archived Template' })
+ archived.update_attributes(archived: true)
+ results = Template.archived
+ assert_equal 1, results.length, 'expected there to be only 1 archived template'
+ assert_equal archived, results.first, 'expected the correct template to have been returned'
+ end
+
+ test "able to determine the latest version number" do
+ version2 = @basic_template.generate_version!
+ version2.save!
+ results = Template.latest_version_per_family(@basic_template.family_id)
+ assert_equal 1, results.length, 'expected only one version to be returned for the specific family'
+ assert_equal version2.version, results.first.version, 'expected the new version'
+ end
+
+ test "able to retrieve the latest version" do
+ version2 = @basic_template.generate_version!
+ version2.save!
+ result = Template.latest_version(@basic_template.family_id)
+ assert_equal 1, result.length, 'expected only one version to be returned'
+ assert_equal version2, result.first, 'expected the new version'
+ end
+
+ test "able to version a template" do
+ template = init_full_template(@basic_template)
+ assert_equal 0, template.version, 'expected the initial template version to be zero'
+ version2 = template.generate_version!
+ assert_equal 1, version2.version, 'expected the version number to be one more than the original template\'s'
+ assert_equal template.family_id, version2.family_id, 'expected the new version to have the same family_id'
+ assert_equal template.visibility, version2.visibility, 'expected the new version to have the same visibility'
+ assert_equal template.is_default, version2.is_default, 'expected the new version to have the same default flag'
+ assert_equal false, version2.archived, 'expected the new version to no be archived'
+ # All components were transferred over to the new version
+ assert_equal template.phases.length, version2.phases.length, 'expected the new version to have the same number of phases'
+ template.phases.each_with_index do |phase, idx|
+ assert_phases_equal(phase, version2.phases[idx])
end
end
- # ---------------------------------------------------
- test "current scope only returns the most recent version for each dmptemplate_id" do
- Org.all.each do |org|
- Template.dmptemplate_ids.each do |dmptemplate_id|
- latest = Template.where(dmptemplate_id: dmptemplate_id).order(updated_at: :desc).first
-
- assert_equal latest, Template.current(dmptemplate_id), "Expected the template.id #{latest.id} to be the current record for Org: #{org.id}, dmptemplate_id: #{dmptemplate_id}"
- end
+ test "#generate_copy! raises RuntimeError when a non Org object is passed" do
+ init_full_template(@basic_template)
+ exception = assert_raises(RuntimeError) do
+ @basic_template.generate_copy!(nil)
+ end
+ assert_equal(_('generate_copy! requires an organisation target'), exception.message)
+ end
+
+ test "#generate_copy! creates a new copy of a template" do
+ template = init_full_template(@basic_template)
+ template.update_attributes(is_default: true, published: true) # Update these flags to verify that the copy sets them properly
+ copy = template.generate_copy!(@institution)
+ assert_not_equal template.id, copy.id, 'expecetd the copy to have a different id'
+ assert_not_equal template.family_id, copy.family_id, 'expected the copy to have a different family id'
+ assert_equal @institution, copy.org, 'expected the copy to have the correct Org'
+ assert_equal 0, copy.version, 'expected the copy\'s version number to be zero'
+ assert_not copy.published?, 'expected the copy to not be published'
+ assert_not copy.is_default?, 'expected the copy to not be the default template'
+ assert_equal 'organisationally_visible', copy.visibility, 'expected the visibility to be organisational'
+ assert_equal 'Copy of %{template}' % { template: template.title }, copy.title, 'expected the template title to be "Copy of %{template}"'
+ assert_equal template.description, copy.description, 'expected the template descriptions to match'
+ assert_equal template.phases.length, copy.phases.length, 'expected the copy to have the same number of phases'
+ template.phases.each_with_index do |phase, idx|
+ assert_phases_equal(phase, copy.phases[idx])
+ end
+ end
+
+ test "can properly determine if current template is the latest version" do
+ assert @basic_template.latest?, 'expected the initial template to be the latest version'
+ version2 = @basic_template.generate_version!
+ version2.save!
+ assert_not @basic_template.latest?, 'expected the initial template to no longer be the latest version'
+ assert version2.latest?, 'expected the new version to be the latest version'
+ end
+
+ test "#customize! raises RuntimeError when a non Org object is passed" do
+ init_full_template(@basic_template)
+ exception = assert_raises(RuntimeError) do
+ @basic_template.customize!(nil)
+ end
+ assert_equal(_('customize! requires an organisation target'), exception.message)
+ end
+
+ test "#customize! raises RuntimeError when the template belongs to a non funder" do
+ template = init_template(@org, published: true)
+ exception = assert_raises(StandardError) do
+ template.customize!(@institution)
end
end
- # ---------------------------------------------------
- test "published scope only returns the current published version for each dmptemplate_id" do
- Org.all.each do |org|
- Template.dmptemplate_ids.each do |dmptemplate_id|
- latest = Template.where(dmptemplate_id: dmptemplate_id, published: true).order(updated_at: :desc).first
+ test "#customize! allows user to customize the default template" do
+ template = init_template(@org, published: true, is_default: true)
+ customization = template.customize!(@institution)
+ assert_not_nil(customization)
+ end
+
+ test "#customize! generates a new template" do
+ template = init_full_template(@basic_template)
+ customization = template.customize!(@institution)
+ assert(customization.family_id.present?, 'expected a newly family_id value')
+ assert_equal(template.family_id, customization.customization_of, 'expected the customization_of id to match the base template\'s family_id')
+ assert_equal(0, customization.version, 'expected the initial customization version to be zero')
+ assert_equal(@institution, customization.org, 'expected the customizatio\'s org to match the one specified')
+ assert_not(customization.published, 'expected the customization to not be published')
+ assert_equal('organisationally_visible', customization.visibility, 'expected the customization\'s visibility to be organisationally visible')
+ assert_not(customization.is_default, 'expected the customization to not be the default template')
- assert_equal latest, Template.live(dmptemplate_id), "Expected the #{latest.nil? ? 'template to have never been published' : "template.id #{latest.id} to be the published record"} for Org: #{org.id}, dmptemplate_id: #{dmptemplate_id}"
- end
+ # Following statements go further than checking that the instance method behaves adequately
+ assert_equal template.phases.length, customization.phases.length, 'expected the customization to have the same number of phases as the base template'
+ template.phases.each_with_index do |phase, idx|
+ assert_phases_equal(phase, customization.phases[idx])
end
end
-
- # ---------------------------------------------------
- test "deep copy" do
- verify_deep_copy(@template, ['id', 'created_at', 'updated_at'])
+ test "#customize! is thread-safe and therefore only one customization_of/version/org_id record exists in the db" do
+ template = init_template(@funder, published: true)
+ await = true
+ should_assert = true
+ threads = 3.times.map do |i|
+ Thread.new do
+ while await do ; end
+ begin
+ template.customize!(@org)
+ rescue ActiveRecord::StatementInvalid => e
+ # SQLite only supports one writer at a time. (e.g. https://www.sqlite.org/rescode.html#busy)
+ should_assert = false if e.message.include?("SQLite3::BusyException")
+ end
+ end
+ end
+ await = false
+ threads.map(&:join)
+ # ActiveRecord::Base.connection.adapter_name != 'SQLite'
+ assert_equal(1, Template.where(customization_of: template.family_id, version: 0, org_id: @org.id).count) if should_assert
end
- # ---------- has_customisations? ----------
- test "has_customisations? correctly identifies if a given org has customised the template" do
- @template.phases.first.modifiable = false
- assert @template.has_customisations?(@org.id, @template), "expected the template to have customisations if it's phase is NOT modifiable"
-
- @template.phases.first.modifiable = true
- assert_not @template.has_customisations?(@org.id, @template), "expected the template to NOT have customisations if it's phase is modifiable"
-
- @template.phases << Phase.new(title: 'New phase test', modifiable: false)
- assert @template.has_customisations?(@org.id, @template), "expected the template to have customisations if all of its phases is NOT modifiable"
-
- @template.phases.last.modifiable = true
- assert_not @template.has_customisations?(@org.id, @template), "expected the template to NOT have customisations if one of its phases is modifiable"
+ test "template customizations can be transferred after base template changes" do
+ init_full_template(@basic_template)
+ customization = @basic_template.customize!(@institution)
+ first_question = customization.phases.first.sections.first.questions.first
+ init_annotation(customization.org, first_question)
+ customization.save!
end
-
- # ---------------------------------------------------
- test "can CRUD Template" do
- tmplt = Template.create(org: @org, version: 1, title: 'Tester')
- assert_not tmplt.id.nil?, "was expecting to be able to create a new Template!"
+ test "base_org returns the current template org if the template is not customized" do
+ assert_equal @basic_template.org, @basic_template.base_org, 'expected an uncustomized template to consider its own org the base_org'
+ end
+ test "base_org returns the parent template org if the template is customized" do
+ customization = @basic_template.customize!(@institution)
+ assert_equal @basic_template.org, customization.base_org, 'expected a customized template to consider the parent template\'s org the base_org'
+ end
- tmplt.description = 'Testing an update'
- tmplt.save!
- tmplt.reload
- assert_equal 'Testing an update', tmplt.description, "Was expecting to be able to update the description of the Template!"
-
- assert tmplt.destroy!, "Was unable to delete the Template!"
+ test "#generate_version! raises RuntimeError when the template is not published" do
+ template = init_template(@org, published: false)
+ exception = assert_raises(RuntimeError) do
+ template.generate_version!
+ end
+ assert_equal(_('generate_version! requires a published template'), exception.message)
+ end
+
+ test "#generate_version! creates a new version for a published and non-customised template" do
+ template = init_template(@org, published: true)
+ new_template = template.generate_version!
+ assert_equal(@basic_template.version + 1, new_template.version)
+ assert_not(new_template.published)
+ end
+
+ test "#generate_version! is thread-safe and therefore only one family_id/version record exists in the db" do
+ template = init_template(@org, published: true)
+ await = true
+ should_assert = true
+ threads = 3.times.map do |i|
+ Thread.new do
+ while await do ; end
+ begin
+ template.generate_version!
+ rescue ActiveRecord::StatementInvalid => e
+ # SQLite only supports one writer at a time. (e.g. https://www.sqlite.org/rescode.html#busy)
+ should_assert = false if e.message.include?("SQLite3::BusyException")
+ end
+ end
+ end
+ await = false
+ threads.map(&:join)
+ assert_equal(1, Template.where(family_id: template.family_id, version: 1).count) if should_assert
+ end
+
+ test "#upgrade_customization! raises RuntimeError when the template is not a customisation of another template" do
+ template = init_template(@org, published: true)
+ exception = assert_raises(RuntimeError) do
+ template.upgrade_customization!
+ end
+ assert_equal(_('upgrade_customization! requires a customised template'), exception.message)
+ end
+
+ test "#upgrade_customization! creates a new version" do
+ customization = @basic_template.customize!(@institution)
+ customization.published = true
+ transferred = customization.upgrade_customization!
+ assert_equal(customization.version + 1, transferred.version, 'expected the version number to have been incremented when the current cusomization was published')
+ assert_equal(customization.family_id, transferred.family_id, 'expected the family_id to be retained when upgrade_customization! is called')
+ end
+
+ test "#upgrade_customization! appends modifiable phases to the new customisation" do
+ init_full_template(@basic_template)
+ customization = @basic_template.customize!(@institution)
+ customization.phases << Phase.new(title: 'New customised phase', number: 2, modifiable: true)
+ customization.phases << Phase.new(title: 'New customised phase 2', number: 3, modifiable: true)
+
+ transferred = customization.upgrade_customization!
+ assert_not_equal(customization.object_id, transferred.object_id, 'customization and transferred are distinct objects')
+ assert_equal(3, transferred.phases.length, 'expected 3 phases after upgrading a customised template')
+ end
+
+ test "#upgrade_customization! appends modifiable sections into an unmodifiable phase" do
+ init_full_template(@basic_template)
+ customization = @basic_template.customize!(@institution)
+ customization.phases.first.sections << Section.new(title: 'New customised section', number: 2, modifiable: true)
+ customization.phases.first.sections << Section.new(title: 'New customised section 2', number: 3, modifiable: true)
+
+ transferred = customization.upgrade_customization!
+ assert_not_equal(customization.object_id, transferred.object_id, 'customization and transferred are distinct objects')
+ assert_equal(3, transferred.phases.first.sections.length, 'expected 3 sections after upgrading a customised template')
+ end
+
+ test "#upgrade_customization! appends modifiable questions into an unmodifiable section" do
+ init_full_template(@basic_template)
+ customization = @basic_template.customize!(@institution)
+ customization.phases.first.sections.first.questions << Question.new(text: 'New customised question', number: 2, modifiable: true)
+ customization.phases.first.sections.first.questions << Question.new(text: 'New customised question 2', number: 3, modifiable: true)
+
+ transferred = customization.upgrade_customization!
+ assert_not_equal(customization.object_id, transferred.object_id, 'customization and transferred are distinct objects')
+ assert_equal(3, transferred.phases.first.sections.first.questions.length, 'expected 3 questions after upgrading a customised template')
+ end
+
+ test "#upgrade_customization! appends annotations added to an unmodifiable question" do
+ init_full_template(@basic_template)
+ customization = @basic_template.customize!(@institution)
+ customization.phases.first.sections.first.questions.first.annotations <<
+ Annotation.new(text: 'New customised guidance', type: Annotation.types[:guidance], org: customization.org)
+ customization.phases.first.sections.first.questions.first.annotations <<
+ Annotation.new(text: 'New customised example_answer', type: Annotation.types[:example_answer], org: customization.org)
+
+ @basic_template.phases.first.sections.first.questions.first.annotations <<
+ Annotation.new(text: 'New funder guidance', type: Annotation.types[:guidance], org: @basic_template.org)
+ @basic_template.phases.first.sections.first.questions.first.annotations <<
+ Annotation.new(text: 'New funder example_answer', type: Annotation.types[:example_answer], org: @basic_template.org)
+
+ transferred = customization.upgrade_customization!
+ assert_not_equal(customization.object_id, transferred.object_id, 'customization and transferred are distinct objects')
+ assert_equal(4, transferred.phases.first.sections.first.questions.first.annotations.length, 'expected 4 annotations after upgrading a customised template')
+ end
+
+ test "#generate_version? returns true when the template is published" do
+ @basic_template.published = true
+ assert(@basic_template.generate_version?)
+ end
+
+ test "#generate_version? returns false when the template is not published" do
+ @basic_template.published = false
+ assert_not(@basic_template.generate_version?)
+ end
+
+ test "#customize? returns false when no org is passed" do
+ assert_not(@basic_template.customize?(nil))
+ end
+
+ test "#customize? returns false when the template is not owned by a funder or is not the default template" do
+ template = init_template(@institution, { title: 'institutional template', is_default: false })
+ assert_not template.customize?(@funder)
+ end
+
+ test "#customize? returns true when the org does not have a customization of the template" do
+ assert(@basic_template.customize?(@institution))
+ end
+
+ test "#customize? returns false when the org has already a customization of the template" do
+ @basic_template.customize!(@institution)
+ assert_not(@basic_template.customize?(@institution))
+ end
+
+ test "#upgrade_customization? returns false when the template is not a customization of another template" do
+ assert_not(@basic_template.upgrade_customization?)
+ end
+
+ test "#upgrade_customization? returns false when the template is already according to the latest published funder template" do
+ @basic_template.published = true
+ customization = @basic_template.customize!(@institution)
+ assert_not(customization.upgrade_customization?)
+ end
+
+ test "#upgrade_customization? returns true when the template is stale, i.e a new version from funder has been published" do
+ @basic_template.published = true
+ customization = @basic_template.customize!(@institution)
+ customization.created_at = customization.created_at.yesterday
+ new_version = @basic_template.generate_version!
+ new_version.published = true
+ new_version.save!
+ assert(customization.upgrade_customization?)
+ end
+
+ test "default template retains the correct flags when versioned" do
+ @basic_template.update!({ org: @org, published: true, is_default: true, visibility: Template.visibilities[:publicly_visible] })
+ new_version = @basic_template.generate_version!
+ assert_not new_version.published?, 'expected the new version to not be published'
+ assert new_version.is_default?, 'expected the new version to be flagged as the default template'
+ assert new_version.publicly_visible?, 'expected the new version to be publicly visible'
end
- # ---------------------------------------------------
- test "can manage has_many relationship with Phase" do
- phase = Phase.new(title: 'Test Phase', number: 2)
- verify_has_many_relationship(@template, phase, @template.phases.count)
+ test " a customization of the default template is not marked as the default" do
+ @basic_template.update!({ org: @org, published: true, is_default: true, visibility: Template.visibilities[:publicly_visible] })
+ customization = @basic_template.customize!(@institution)
+ assert_not customization.published?, 'expected the customization to not be published'
+ assert_not customization.is_default?, 'expected the customization to not be flagged as the default template'
+ assert_not customization.publicly_visible?, 'expected the customization to not be publicly visible'
+ end
+
+ test "::find_or_generate_version! raises RuntimeError when attempting to retrieve a historical version for being modified" do
+ @basic_template.generate_version!
+ exception = assert_raises(RuntimeError) do
+ Template.find_or_generate_version!(@basic_template)
+ end
+ assert_equal(_('A historical template cannot be retrieved for being modified'), exception.message)
+ end
+
+ test "::find_or_generate_version! does not generate a new version" do
+ new_template = @basic_template.generate_version!
+ template = Template.find_or_generate_version!(new_template)
+ assert_equal(new_template, template)
+ end
+
+ test "::find_or_generate_version! generates a new version" do
+ template = Template.find_or_generate_version!(@basic_template)
+ assert_not_equal(@basic_template, template)
+ end
+
+ test "publishing a template automatically unpublishes other versions" do
+ @basic_template.published = true
+ @basic_template.save!
+ v2 = @basic_template.generate_version!
+ v2.published = true
+ v2.save!
+ assert v2.reload.published?, 'expected the new version to be published'
+ assert_not @basic_template.reload.published?, 'expected the old version to be unpublished'
+ end
+
+ test "draft? returns false for a published template" do
+ @basic_template.published = true
+ assert_not @basic_template.draft?
end
- # ---------------------------------------------------
- test "can manage has_many relationship with Plan" do
- plan = Plan.new(title: 'Test Plan', visibility: :is_test)
- verify_has_many_relationship(@template, plan, @template.plans.count)
- end
-
- # ---------------------------------------------------
- test "can manage belongs_to relationship with Org" do
- tmplt = Template.new(title: 'My test', version: 1)
- verify_belongs_to_relationship(tmplt, @org)
- end
-
- test 'should be invalid when links is not a hash' do
- t = Template.new(title: 'My test', version: 1, org: @org)
- t.links = []
- refute(t.valid?)
- assert_equal(['A hash is expected for links'], t.errors.messages[:links])
- end
-
- test 'should be invalid when links hash does not have the expected keys' do
- t = Template.new(title: 'My test', version: 1, org: @org)
- t.links = { "foo" => [], "bar" => [] }
- refute(t.valid?)
- assert_equal(['A key funder is expected for links hash', 'A key sample_plan is expected for links hash'], t.errors.messages[:links])
- end
-
- test 'should be invalid when links hash keys are not compliant to object links format' do
- t = Template.new(title: 'My test', version: 1, org: @org)
- t.links = { "funder" => [{}], "sample_plan" => [{}] }
- refute(t.valid?)
- assert_equal(['The key funder does not have a valid set of object links', 'The key sample_plan does not have a valid set of object links'], t.errors.messages[:links])
- end
-
- test 'should be valid when links hash keys are compliant to object links format' do
- t = Template.new(title: 'My test', version: 1, org: @org)
- t.links = { "funder" => [{ "link" => "foo", "text" => "bar" }], "sample_plan" => [] }
- assert(t.valid?)
- assert_equal(nil, t.errors.messages[:links])
+ test "draft? returns true for an unpublished version of a template that has a published version" do
+ @basic_template.published = true
+ version = @basic_template.generate_version!
+ assert version.draft?
end
- test 'should return the latest customizations for the Org' do
- tA = Template.create!(title: 'My test A', version: 0, org: @org)
- tB = Template.create!(title: 'My test B', version: 0, org: @org)
- tC = Template.create!(title: 'My test C', version: 0, org: @org)
-
- # Test 1 - Multiple versions
- cAv0 = Template.create!(title: 'My test customization A', version: 0, customization_of: tA.dmptemplate_id, org: Org.first)
- cAv1 = Template.deep_copy(cAv0)
- cAv1.update_attributes(version: 1)
-
- # Test 2 - Only one version
- cBv0 = Template.create!(title: 'My test customization B', version: 0, customization_of: tB.dmptemplate_id, org: Org.first)
-
- # Test 3 - Make sure it always returns the latest version regardless of published statuses
- cCv0 = Template.create!(title: 'My test customization C', version: 0, customization_of: tC.dmptemplate_id, org: Org.first)
- cCv1 = Template.deep_copy(cCv0)
- cCv1.update_attributes(version: 1, published: true)
- cCv2 = Template.deep_copy(cCv1)
- cCv2.update_attributes(version: 2)
-
- latest = Template.org_customizations([tA, tB, tC].collect(&:dmptemplate_id), Org.first.id)
- assert latest.include?(cAv1), 'expected to get customization A - version 1.'
- assert latest.include?(cBv0), 'expected to get customization B - version 0.'
- assert latest.include?(cCv2), 'expected to get customization C - version 2.'
+ test "draft? returns false for a template that has no published versions" do
+ @basic_template.published = true
+ version = @basic_template.generate_version!
+ @basic_template.update(published: false)
+ assert_not version.draft?
end
end
diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb
index 0fa96b6..9a1dbce 100644
--- a/test/unit/user_test.rb
+++ b/test/unit/user_test.rb
@@ -15,6 +15,15 @@
org: Org.last,
api_token: 'ABC123',
language: Language.find_by(abbreviation: I18n.locale))
+
+ @notification = Notification.create!(
+ notification_type: Notification.notification_types[:global],
+ title: 'notification_1',
+ level: Notification.levels[:info],
+ body: 'notification 1',
+ dismissable: false,
+ starts_at: Date.today,
+ expires_at: Date.tomorrow)
end
# ---------------------------------------------------
@@ -349,4 +358,16 @@
assert_equal(previous_api_token, @user.api_token)
assert_equal(previous_perms, @user.perms)
end
+
+ # Cannot dismiss Notifications that are non-dismissable
+ test 'cannot acknowledge a notification that is not dismissable' do
+ @user.acknowledge(@notification)
+ assert_not(@notification.acknowledged?(@user))
+ end
+ # Can dismiss Notifications that are dismissable
+ test 'can acknowledge a notification' do
+ @notification.update!(dismissable: true)
+ @user.acknowledge(@notification)
+ assert(@notification.acknowledged?(@user))
+ end
end