diff --git a/services/web/app/coffee/Features/Collaborators/CollaboratorsEmailHandler.coffee b/services/web/app/coffee/Features/Collaborators/CollaboratorsEmailHandler.coffee
index f669d85de4..bc7eb90c3f 100644
--- a/services/web/app/coffee/Features/Collaborators/CollaboratorsEmailHandler.coffee
+++ b/services/web/app/coffee/Features/Collaborators/CollaboratorsEmailHandler.coffee
@@ -11,27 +11,6 @@ module.exports = CollaboratorsEmailHandler =
"user_first_name=#{encodeURIComponent(project.owner_ref.first_name)}"
].join("&")
- notifyUserOfProjectShare: (project_id, email, callback)->
- Project
- .findOne(_id: project_id )
- .select("name owner_ref")
- .populate('owner_ref')
- .exec (err, project)->
- emailOptions =
- to: email
- replyTo: project.owner_ref.email
- project:
- name: project.name
- url: "#{Settings.siteUrl}/project/#{project._id}?" + [
- "project_name=#{encodeURIComponent(project.name)}"
- "user_first_name=#{encodeURIComponent(project.owner_ref.first_name)}"
- "new_email=#{encodeURIComponent(email)}"
- "r=#{project.owner_ref.referal_id}" # Referal
- "rs=ci" # referral source = collaborator invite
- ].join("&")
- owner: project.owner_ref
- EmailHandler.sendEmail "projectSharedWithYou", emailOptions, callback
-
notifyUserOfProjectInvite: (project_id, email, invite, callback)->
Project
.findOne(_id: project_id )
diff --git a/services/web/app/coffee/Features/Email/EmailBuilder.coffee b/services/web/app/coffee/Features/Email/EmailBuilder.coffee
index 5ceece048e..70d11e219b 100644
--- a/services/web/app/coffee/Features/Email/EmailBuilder.coffee
+++ b/services/web/app/coffee/Features/Email/EmailBuilder.coffee
@@ -7,10 +7,18 @@ settings = require("settings-sharelatex")
templates = {}
+
templates.registered =
subject: _.template "Activate your #{settings.appName} Account"
layout: PersonalEmailLayout
type: "notification"
+ plainTextTemplate: _.template """
+Congratulations, you've just had an account created for you on #{settings.appName} with the email address "<%= to %>".
+
+Click here to set your password and log in: <%= setNewPasswordUrl %>
+
+If you have any questions or problems, please contact #{settings.adminEmail}
+"""
compiledTemplate: _.template """
Congratulations, you've just had an account created for you on #{settings.appName} with the email address "<%= to %>".
@@ -19,10 +27,24 @@ templates.registered =
If you have any questions or problems, please contact #{settings.adminEmail}.
"""
+
templates.canceledSubscription =
subject: _.template "ShareLaTeX thoughts"
layout: PersonalEmailLayout
type:"lifecycle"
+ plainTextTemplate: _.template """
+Hi <%= first_name %>,
+
+I'm sorry to see you cancelled your ShareLaTeX premium account. Would you mind giving me some advice on what the site is lacking at the moment via this survey?:
+
+https://sharelatex.typeform.com/to/f5lBiZ
+
+Thank you in advance.
+
+Henry
+
+ShareLaTeX Co-founder
+"""
compiledTemplate: _.template '''
Hi <%= first_name %>,
@@ -36,10 +58,26 @@ ShareLaTeX Co-founder
'''
+
templates.passwordResetRequested =
subject: _.template "Password Reset - #{settings.appName}"
layout: NotificationEmailLayout
type:"notification"
+ plainTextTemplate: _.template """
+Password Reset
+
+We got a request to reset your #{settings.appName} password.
+
+Click this link to reset your password: <%= setNewPasswordUrl %>
+
+If you ignore this message, your password won't be changed.
+
+If you didn't request a password reset, let us know.
+
+Thank you
+
+#{settings.appName} - <%= siteUrl %>
+"""
compiledTemplate: _.template """
Password Reset
@@ -66,26 +104,6 @@ If you didn't request a password reset, let us know.
#{settings.appName}
"""
-templates.projectSharedWithYou =
- subject: _.template "<%= owner.email %> wants to share <%= project.name %> with you"
- layout: NotificationEmailLayout
- type:"notification"
- compiledTemplate: _.template """
-Hi, <%= owner.email %> wants to share '<%= project.name %>' with you
-
-
-
- Thank you
- #{settings.appName}
-"""
templates.projectInvite =
subject: _.template "<%= project.name %> - shared by <%= owner.email %>"
@@ -113,10 +131,20 @@ Thank you
#{settings.appName}
"""
+
templates.completeJoinGroupAccount =
subject: _.template "Verify Email to join <%= group_name %> group"
layout: NotificationEmailLayout
type:"notification"
+ plainTextTemplate: _.template """
+Hi, please verify your email to join the <%= group_name %> and get your free premium account
+
+Click this link to verify now: <%= completeJoinUrl %>
+
+Thank You
+
+#{settings.appName} - <%= siteUrl %>
+"""
compiledTemplate: _.template """
Hi, please verify your email to join the <%= group_name %> and get your free premium account
@@ -134,6 +162,7 @@ templates.completeJoinGroupAccount =
#{settings.appName}
"""
+
module.exports =
templates: templates
diff --git a/services/web/app/coffee/Features/HealthCheck/HealthCheckController.coffee b/services/web/app/coffee/Features/HealthCheck/HealthCheckController.coffee
index 5ed5b85e08..9aec67e14e 100644
--- a/services/web/app/coffee/Features/HealthCheck/HealthCheckController.coffee
+++ b/services/web/app/coffee/Features/HealthCheck/HealthCheckController.coffee
@@ -63,6 +63,7 @@ Reporter = (res) ->
res.contentType("application/json")
if failures.length > 0
+ logger.err failures:failures, "health check failed"
res.send 500, JSON.stringify(results, null, 2)
else
res.send 200, JSON.stringify(results, null, 2)
diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee
index 9b812d8d17..51b3db8f56 100644
--- a/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee
+++ b/services/web/app/coffee/Features/Subscription/SubscriptionController.coffee
@@ -8,6 +8,7 @@ Settings = require 'settings-sharelatex'
logger = require('logger-sharelatex')
GeoIpLookup = require("../../infrastructure/GeoIpLookup")
SubscriptionDomainHandler = require("./SubscriptionDomainHandler")
+UserGetter = require "../User/UserGetter"
module.exports = SubscriptionController =
@@ -21,14 +22,25 @@ module.exports = SubscriptionController =
if req.query.v?
viewName = "#{viewName}_#{req.query.v}"
logger.log viewName:viewName, "showing plans page"
+ currentUser = null
GeoIpLookup.getCurrencyCode req.query?.ip || req.ip, (err, recomendedCurrency)->
return next(err) if err?
- res.render viewName,
- title: "plans_and_pricing"
- plans: plans
- baseUrl: baseUrl
- gaExperiments: Settings.gaExperiments.plansPage
- recomendedCurrency:recomendedCurrency
+ render = () ->
+ res.render viewName,
+ title: "plans_and_pricing"
+ plans: plans
+ baseUrl: baseUrl
+ gaExperiments: Settings.gaExperiments.plansPage
+ recomendedCurrency:recomendedCurrency
+ shouldABTestPlans: currentUser == null or (currentUser?.signUpDate? and currentUser.signUpDate >= (new Date('2016-10-27')))
+ user_id = AuthenticationController.getLoggedInUserId(req)
+ if user_id?
+ UserGetter.getUser user_id, {signUpDate: 1}, (err, user) ->
+ return next(err) if err?
+ currentUser = user
+ render()
+ else
+ render()
#get to show the recurly.js page
paymentPage: (req, res, next) ->
diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee
index 44c31c8d60..8e2fc2032e 100644
--- a/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee
+++ b/services/web/app/coffee/Features/Subscription/SubscriptionViewModelBuilder.coffee
@@ -44,7 +44,7 @@ module.exports =
allPlans = {}
plans.forEach (plan)->
allPlans[plan.planCode] = plan
-
+
result =
allPlans: allPlans
@@ -54,7 +54,7 @@ module.exports =
result.studentAccounts = _.filter plans, (plan)->
plan.planCode.indexOf("student") != -1
-
+
result.groupMonthlyPlans = _.filter plans, (plan)->
plan.groupPlan and !plan.annual
@@ -68,4 +68,3 @@ module.exports =
!plan.groupPlan and plan.annual and plan.planCode.indexOf("student") == -1
return result
-
diff --git a/services/web/app/coffee/Features/User/UserController.coffee b/services/web/app/coffee/Features/User/UserController.coffee
index 389de1a0f2..47c093d590 100644
--- a/services/web/app/coffee/Features/User/UserController.coffee
+++ b/services/web/app/coffee/Features/User/UserController.coffee
@@ -15,12 +15,26 @@ settings = require "settings-sharelatex"
module.exports = UserController =
- deleteUser: (req, res)->
+ tryDeleteUser: (req, res, next) ->
user_id = AuthenticationController.getLoggedInUserId(req)
- UserDeleter.deleteUser user_id, (err)->
- if !err?
+ password = req.body.password
+ logger.log {user_id}, "trying to delete user account"
+ if !password? or password == ''
+ logger.err {user_id}, 'no password supplied for attempt to delete account'
+ return res.sendStatus(403)
+ AuthenticationManager.authenticate {_id: user_id}, password, (err, user) ->
+ if err?
+ logger.err {user_id}, 'error authenticating during attempt to delete account'
+ return next(err)
+ if !user
+ logger.err {user_id}, 'auth failed during attempt to delete account'
+ return res.sendStatus(403)
+ UserDeleter.deleteUser user_id, (err) ->
+ if err?
+ logger.err {user_id}, "error while deleting user account"
+ return next(err)
req.session?.destroy()
- res.sendStatus(200)
+ res.sendStatus(200)
unsubscribe: (req, res)->
user_id = AuthenticationController.getLoggedInUserId(req)
@@ -143,7 +157,7 @@ module.exports = UserController =
type:'success'
text:'Your password has been changed'
else
- logger.log user: user, "current password wrong"
+ logger.log user_id: user_id, "current password wrong"
res.send
message:
type:'error'
diff --git a/services/web/app/coffee/infrastructure/ExpressLocals.coffee b/services/web/app/coffee/infrastructure/ExpressLocals.coffee
index 8763624516..c699332f46 100644
--- a/services/web/app/coffee/infrastructure/ExpressLocals.coffee
+++ b/services/web/app/coffee/infrastructure/ExpressLocals.coffee
@@ -39,7 +39,7 @@ pathList = [
["#{jsPath}ide.js"]
["#{jsPath}main.js"]
["#{jsPath}libs.js"]
- ["#{jsPath}#{ace}/ace.js","#{jsPath}#{ace}/mode-latex.js", "#{jsPath}#{ace}/snippets/latex.js"]
+ ["#{jsPath}#{ace}/ace.js","#{jsPath}#{ace}/mode-latex.js","#{jsPath}#{ace}/worker-latex.js","#{jsPath}#{ace}/snippets/latex.js"]
["#{jsPath}libs/#{pdfjs}/pdf.js"]
["#{jsPath}libs/#{pdfjs}/pdf.worker.js"]
["#{jsPath}libs/#{pdfjs}/compatibility.js"]
diff --git a/services/web/app/coffee/infrastructure/LoggerSerializers.coffee b/services/web/app/coffee/infrastructure/LoggerSerializers.coffee
index f496b8cdad..7bd90c3bf5 100644
--- a/services/web/app/coffee/infrastructure/LoggerSerializers.coffee
+++ b/services/web/app/coffee/infrastructure/LoggerSerializers.coffee
@@ -1,5 +1,7 @@
module.exports =
user: (user) ->
+ if !user?
+ return null
if !user._id?
user = {_id : user}
return {
@@ -10,6 +12,8 @@ module.exports =
}
project: (project) ->
+ if !project?
+ return null
if !project._id?
project = {_id: project}
return {
diff --git a/services/web/app/coffee/router.coffee b/services/web/app/coffee/router.coffee
index 56dd8d821b..a027f6359e 100644
--- a/services/web/app/coffee/router.coffee
+++ b/services/web/app/coffee/router.coffee
@@ -92,7 +92,7 @@ module.exports = class Router
webRouter.post '/user/sessions/clear', AuthenticationController.requireLogin(), UserController.clearSessions
webRouter.delete '/user/newsletter/unsubscribe', AuthenticationController.requireLogin(), UserController.unsubscribe
- webRouter.delete '/user', AuthenticationController.requireLogin(), UserController.deleteUser
+ webRouter.post '/user/delete', AuthenticationController.requireLogin(), UserController.tryDeleteUser
webRouter.get '/user/personal_info', AuthenticationController.requireLogin(), UserInfoController.getLoggedInUsersPersonalInfo
apiRouter.get '/user/:user_id/personal_info', AuthenticationController.httpAuth, UserInfoController.getPersonalInfo
diff --git a/services/web/app/views/layout.jade b/services/web/app/views/layout.jade
index 7f5cfd891f..8f4d1263db 100644
--- a/services/web/app/views/layout.jade
+++ b/services/web/app/views/layout.jade
@@ -51,8 +51,6 @@ html(itemscope, itemtype='http://schema.org/Product')
script(type="text/javascript").
window.csrfToken = "#{csrfToken}";
- block scripts
-
script(src=buildJsPath("libs/jquery-1.11.1.min.js", {fingerprint:false}))
script(type="text/javascript").
var noCdnKey = "nocdn=true"
@@ -61,6 +59,9 @@ html(itemscope, itemtype='http://schema.org/Product')
if (cdnBlocked && !noCdnAlreadyInUrl && navigator.userAgent.indexOf("Googlebot") == -1) {
window.location.search += '&'+noCdnKey;
}
+
+ block scripts
+
script(src=buildJsPath("libs/angular-1.3.15.min.js", {fingerprint:false}))
script.
diff --git a/services/web/app/views/project/editor.jade b/services/web/app/views/project/editor.jade
index e119101634..8bcbc1976d 100644
--- a/services/web/app/views/project/editor.jade
+++ b/services/web/app/views/project/editor.jade
@@ -118,6 +118,9 @@ block requirejs
"ace/ext-searchbox": {
"deps": ["ace/ace"]
},
+ "ace/ext-modelist": {
+ "deps": ["ace/ace"]
+ },
"ace/ext-language_tools": {
"deps": ["ace/ace"]
}
diff --git a/services/web/app/views/project/editor/editor.jade b/services/web/app/views/project/editor/editor.jade
index f33e79ee12..94ae6ceb6e 100644
--- a/services/web/app/views/project/editor/editor.jade
+++ b/services/web/app/views/project/editor/editor.jade
@@ -35,6 +35,7 @@ div.full-size(
resize-on="layout:main:resize,layout:pdf:resize,layout:review:resize,reviewPanel:toggle",
annotations="pdf.logEntryAnnotations[editor.open_doc_id]",
read-only="!permissions.write",
+ file-name="editor.open_doc_name",
on-ctrl-enter="recompileViaKey",
syntax-validation="settings.syntaxValidation",
review-panel="reviewPanel",
diff --git a/services/web/app/views/project/editor/history.jade b/services/web/app/views/project/editor/history.jade
index 9cf756c344..3799b22363 100644
--- a/services/web/app/views/project/editor/history.jade
+++ b/services/web/app/views/project/editor/history.jade
@@ -1,41 +1,85 @@
div#history(ng-show="ui.view == 'history'")
span(ng-controller="HistoryPremiumPopup")
- .upgrade-prompt(ng-show="!project.features.versioning")
- .message(ng-show="project.owner._id == user.id")
- p.text-center: strong #{translate("upgrade_to_get_feature", {feature:"full Project History"})}
- p.text-center.small(ng-show="startedFreeTrial") #{translate("refresh_page_after_starting_free_trial")}
- ul.list-unstyled
- li
- i.fa.fa-check
- | #{translate("unlimited_projects")}
-
- li
- i.fa.fa-check
- | #{translate("collabs_per_proj", {collabcount:'Multiple'})}
-
- li
- i.fa.fa-check
- | #{translate("full_doc_history")}
-
- li
- i.fa.fa-check
- | #{translate("sync_to_dropbox")}
+ .upgrade-prompt(ng-if="project.features.versioning === false && ui.view === 'history'")
+
+ div(sixpack-switch="teaser-history")
+ .message(
+ sixpack-default
+ ng-show="project.owner._id == user.id"
+ )
+ p.text-center: strong #{translate("upgrade_to_get_feature", {feature:"full Project History"})}
+ p.text-center.small(ng-show="startedFreeTrial") #{translate("refresh_page_after_starting_free_trial")}
+ ul.list-unstyled
+ li
+ i.fa.fa-check
+ | #{translate("unlimited_projects")}
+
+ li
+ i.fa.fa-check
+ | #{translate("collabs_per_proj", {collabcount:'Multiple'})}
+
+ li
+ i.fa.fa-check
+ | #{translate("full_doc_history")}
+
+ li
+ i.fa.fa-check
+ | #{translate("sync_to_dropbox")}
- li
- i.fa.fa-check
- | #{translate("sync_to_github")}
+ li
+ i.fa.fa-check
+ | #{translate("sync_to_github")}
- li
- i.fa.fa-check
- |#{translate("compile_larger_projects")}
+ li
+ i.fa.fa-check
+ |#{translate("compile_larger_projects")}
+ p.text-center(ng-controller="FreeTrialModalController")
+ a.btn.btn-success(
+ href
+ ng-class="buttonClass"
+ ng-click="startFreeTrial('history')"
+ sixpack-convert="teaser-history"
+ ) #{translate("start_free_trial")}
- p.text-center(ng-controller="FreeTrialModalController")
- a.btn.btn-success(
- href
- ng-class="buttonClass"
- ng-click="startFreeTrial('history')"
- ) #{translate("start_free_trial")}
+ .message.message-wider(
+ sixpack-when="focused"
+ ng-show="project.owner._id == user.id"
+ )
+ header.message-header
+ h3 History
+ .message-body
+ h4.teaser-title See who changed what. Go back to previous versions.
+ img.teaser-img(
+ src="/img/teasers/history/teaser-history.png"
+ alt="History"
+ )
+ p.text-center.small(ng-show="startedFreeTrial") #{translate("refresh_page_after_starting_free_trial")}
+ .row
+ .col-md-8.col-md-offset-2
+ ul.list-unstyled
+ li
+ i.fa.fa-check
+ | Catch up with your collaborators changes
+
+ li
+ i.fa.fa-check
+ | See changes over any time period
+
+ li
+ i.fa.fa-check
+ | Revert your documents to previous versions
+
+ li
+ i.fa.fa-check
+ | Restore deleted files
+ p.text-center(ng-controller="FreeTrialModalController")
+ a.btn.btn-success(
+ href
+ ng-class="buttonClass"
+ ng-click="startFreeTrial('history')"
+ sixpack-convert="teaser-history"
+ ) Try it for free
.message(ng-show="project.owner._id != user.id")
p #{translate("ask_proj_owner_to_upgrade_for_history")}
diff --git a/services/web/app/views/subscriptions/dashboard.jade b/services/web/app/views/subscriptions/dashboard.jade
index 34493e5a8c..175c8d1e4f 100644
--- a/services/web/app/views/subscriptions/dashboard.jade
+++ b/services/web/app/views/subscriptions/dashboard.jade
@@ -12,8 +12,8 @@ block scripts
mixin printPlan(plan)
-if (!plan.hideFromUsers)
- tr(ng-controller="ChangePlanFormController")
- td(ng-init="plan=#{JSON.stringify(plan)}")
+ tr(ng-controller="ChangePlanFormController", ng-init="plan=#{JSON.stringify(plan)}", ng-show="shouldShowPlan(plan.planCode)")
+ td
strong #{plan.name}
td {{refreshPrice(plan.planCode)}}
-if (plan.annual)
@@ -46,8 +46,8 @@ block content
|
| #{translate("your_billing_details_were_saved")}
.card(ng-if="view == 'overview'")
- .page-header
- h1 #{translate("your_subscription")}
+ .page-header(x-current-plan="#{subscription.planCode}")
+ h1 #{translate("your_subscription")}
- if (subscription && user._id+'' == subscription.admin_id+'')
case subscription.state
@@ -56,7 +56,8 @@ block content
when "active"
p !{translate("currently_subscribed_to_plan", {planName:"" + subscription.name + ""})}
- a(href, ng-click="changePlan = true") !{translate("change_plan")}.
+ span(ng-show="!isNextGenPlan")
+ a(href, ng-click="changePlan = true") !{translate("change_plan")}.
p !{translate("next_payment_of_x_collectected_on_y", {paymentAmmount:"" + subscription.price + "", collectionDate:"" + subscription.nextPaymentDueAt + ""})}
p.pull-right
p
diff --git a/services/web/app/views/subscriptions/plans.jade b/services/web/app/views/subscriptions/plans.jade
index 9db21fa3a6..d87f601889 100644
--- a/services/web/app/views/subscriptions/plans.jade
+++ b/services/web/app/views/subscriptions/plans.jade
@@ -3,6 +3,7 @@ block scripts
script(type='text/javascript').
window.recomendedCurrency = '#{recomendedCurrency}'
window.abCurrencyFlag = '#{abCurrencyFlag}'
+ window.shouldABTestPlans = #{shouldABTestPlans || false}
script(type='text/javascript').
(function() {var s=document.createElement('script'); s.type='text/javascript';s.async=true;
@@ -56,133 +57,144 @@ block content
ng-click="changeCurreny(currency)"
) {{currency}} ({{value['symbol']}})
- .row(ng-cloak)
- .col-md-10.col-md-offset-1
- .row
- .card-group.text-centered(ng-if="ui.view == 'monthly' || ui.view == 'annual'")
- .col-md-4
- .card.card-first
- .card-header
- h2 #{translate("personal")}
- .circle #{translate("free")}
- ul.list-unstyled
- li #{translate("one_collaborator")}
- li
- li
- li
- li
- br
- a.btn.btn-info(
- href="/register"
- style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden")
- ) #{translate("sign_up_now")}
- .col-md-4
- .card.card-highlighted
- .card-header
- h2 #{translate("collaborator")}
- .circle
- span(ng-if="ui.view == 'monthly'")
- | {{plans[currencyCode]['collaborator']['monthly']}}
- span.small /mo
- span(ng-if="ui.view == 'annual'")
- | {{plans[currencyCode]['collaborator']['annual']}}
- span.small /yr
- ul.list-unstyled
- li
- strong #{translate("collabs_per_proj", {collabcount:10})}
- li #{translate("full_doc_history")}
- li #{translate("sync_to_dropbox")}
- li #{translate("sync_to_github")}
- li
- br
- a.btn.btn-info(
+ div(ng-show="showPlans")
+ .row(ng-cloak)
+ .col-md-10.col-md-offset-1
+ .row
+ .card-group.text-centered(ng-if="ui.view == 'monthly' || ui.view == 'annual'")
+ .col-md-4
+ .card.card-first
+ .card-header
+ h2 #{translate("personal")}
+ .circle #{translate("free")}
+ ul.list-unstyled
+ li #{translate("one_collaborator")}
+ li
+ li
+ li
+ li
+ br
+ a.btn.btn-info(
+ href="/register"
+ style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden")
+ ) #{translate("sign_up_now")}
+ .col-md-4
+ .card.card-highlighted
+ .card-header
+ h2 #{translate("collaborator")}
+ .circle
+ span(ng-if="ui.view == 'monthly'")
+ | {{plans[currencyCode]['collaborator']['monthly']}}
+ span.small /mo
+ span(ng-if="ui.view == 'annual'")
+ | {{plans[currencyCode]['collaborator']['annual']}}
+ span.small /yr
+ ul.list-unstyled
+ li
+ strong(ng-show="plansVariant == 'default'") #{translate("collabs_per_proj", {collabcount:10})}
+ strong(ng-show="plansVariant == 'heron'") #{translate("collabs_per_proj", {collabcount:8})}
+ strong(ng-show="plansVariant == 'ibis'") #{translate("collabs_per_proj", {collabcount:12})}
+ li #{translate("full_doc_history")}
+ li #{translate("sync_to_dropbox")}
+ li #{translate("sync_to_github")}
+ li
+ br
+ a.btn.btn-info(
+
+ ng-href="#{baseUrl}/user/subscription/new?planCode=collaborator{{ (ui.view == 'annual' ? '-annual' : '') + (plansVariant == 'default' ? planQueryString : '_'+plansVariant)}}¤cy={{currencyCode}}", ng-click="signUpNowClicked('collaborator')"
+ )
+ span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")}
+ span(ng-show="ui.view == 'annual'") #{translate("buy_now")}
+ .col-md-4
+ .card.card-last
+ .card-header
+ h2 #{translate("professional")}
+ .circle
+ span(ng-if="ui.view == 'monthly'")
+ | {{plans[currencyCode]['professional']['monthly']}}
+ span.small /mo
+ span(ng-if="ui.view == 'annual'")
+ | {{plans[currencyCode]['professional']['annual']}}
+ span.small /yr
+ ul.list-unstyled
+ li
+ strong #{translate("unlimited_collabs")}
+ li #{translate("full_doc_history")}
+ li #{translate("sync_to_dropbox")}
+ li #{translate("sync_to_github")}
+ li
+ br
+ a.btn.btn-info(
+ ng-href="#{baseUrl}/user/subscription/new?planCode=professional{{ ui.view == 'annual' && '-annual' || planQueryString}}¤cy={{currencyCode}}", ng-click="signUpNowClicked('professional')"
+ )
+ span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")}
+ span(ng-show="ui.view == 'annual'") #{translate("buy_now")}
+
+ .card-group.text-centered(ng-if="ui.view == 'student'")
+ .col-md-4
+ .card.card-first
+ .card-header
+ h2 #{translate("personal")}
+ .circle #{translate("free")}
+ ul.list-unstyled
+ li #{translate("one_collaborator")}
+ li
+ li
+ li
+ li
+ br
+ a.btn.btn-info(
+ href="/register"
+ style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden")
+ ) #{translate("sign_up_now")}
+
+ .col-md-4
+ .card.card-highlighted
+ .card-header
+ h2 #{translate("student")}
+ .circle
+ span
+ | {{plans[currencyCode]['student']['monthly']}}
+ span.small /mo
+ ul.list-unstyled
+ li
+ strong(ng-show="plansVariant == 'default'") #{translate("collabs_per_proj", {collabcount:6})}
+ strong(ng-show="plansVariant == 'heron'") #{translate("collabs_per_proj", {collabcount:4})}
+ strong(ng-show="plansVariant == 'ibis'") #{translate("collabs_per_proj", {collabcount:8})}
+ li #{translate("full_doc_history")}
+ li #{translate("sync_to_dropbox")}
+ li #{translate("sync_to_github")}
+ li
+ br
+ a.btn.btn-info(
+ ng-href="#{baseUrl}/user/subscription/new?planCode=student{{ plansVariant == 'default' ? planQueryString : '_'+plansVariant }}¤cy={{currencyCode}}",
+ ng-click="signUpNowClicked('student')"
+ ) #{translate("start_free_trial")}
+
+ .col-md-4
+ .card.card-last
+ .card-header
+ h2 #{translate("student")} (#{translate("annual")})
+ .circle
+ span
+ | {{plans[currencyCode]['student']['annual']}}
+ span.small /yr
+ ul.list-unstyled
+ li
+ strong(ng-show="plansVariant == 'default'") #{translate("collabs_per_proj", {collabcount:6})}
+ strong(ng-show="plansVariant == 'heron'") #{translate("collabs_per_proj", {collabcount:4})}
+ strong(ng-show="plansVariant == 'ibis'") #{translate("collabs_per_proj", {collabcount:8})}
+ li #{translate("full_doc_history")}
+ li #{translate("sync_to_dropbox")}
+ li #{translate("sync_to_github")}
+ li
+ br
+ a.btn.btn-info(
+ ng-href="#{baseUrl}/user/subscription/new?planCode=student-annual{{ plansVariant == 'default' ? '' : '_'+plansVariant }}¤cy={{currencyCode}}",
+ ng-click="signUpNowClicked('student')"
+ ) #{translate("buy_now")}
- ng-href="#{baseUrl}/user/subscription/new?planCode=collaborator{{ ui.view == 'annual' && '-annual' || planQueryString}}¤cy={{currencyCode}}", ng-click="signUpNowClicked('collaborator')"
- )
- span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")}
- span(ng-show="ui.view == 'annual'") #{translate("buy_now")}
- .col-md-4
- .card.card-last
- .card-header
- h2 #{translate("professional")}
- .circle
- span(ng-if="ui.view == 'monthly'")
- | {{plans[currencyCode]['professional']['monthly']}}
- span.small /mo
- span(ng-if="ui.view == 'annual'")
- | {{plans[currencyCode]['professional']['annual']}}
- span.small /yr
- ul.list-unstyled
- li
- strong #{translate("unlimited_collabs")}
- li #{translate("full_doc_history")}
- li #{translate("sync_to_dropbox")}
- li #{translate("sync_to_github")}
- li
- br
- a.btn.btn-info(
- ng-href="#{baseUrl}/user/subscription/new?planCode=professional{{ ui.view == 'annual' && '-annual' || planQueryString}}¤cy={{currencyCode}}", ng-click="signUpNowClicked('professional')"
- )
- span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")}
- span(ng-show="ui.view == 'annual'") #{translate("buy_now")}
- .card-group.text-centered(ng-if="ui.view == 'student'")
- .col-md-4
- .card.card-first
- .card-header
- h2 #{translate("personal")}
- .circle #{translate("free")}
- ul.list-unstyled
- li #{translate("one_collaborator")}
- li
- li
- li
- li
- br
- a.btn.btn-info(
- href="/register"
- style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden")
- ) #{translate("sign_up_now")}
-
- .col-md-4
- .card.card-highlighted
- .card-header
- h2 #{translate("student")}
- .circle
- span
- | {{plans[currencyCode]['student']['monthly']}}
- span.small /mo
- ul.list-unstyled
- li
- strong #{translate("collabs_per_proj", {collabcount:6})}
- li #{translate("full_doc_history")}
- li #{translate("sync_to_dropbox")}
- li #{translate("sync_to_github")}
- li
- br
- a.btn.btn-info(
- ng-href="#{baseUrl}/user/subscription/new?planCode=student{{planQueryString}}¤cy={{currencyCode}}", ng-click="signUpNowClicked('student')"
- ) #{translate("start_free_trial")}
-
- .col-md-4
- .card.card-last
- .card-header
- h2 #{translate("student")} (#{translate("annual")})
- .circle
- span
- | {{plans[currencyCode]['student']['annual']}}
- span.small /yr
- ul.list-unstyled
- li
- strong #{translate("collabs_per_proj", {collabcount:6})}
- li #{translate("full_doc_history")}
- li #{translate("sync_to_dropbox")}
- li #{translate("sync_to_github")}
- li
- br
- a.btn.btn-info(
- ng-href="#{baseUrl}/user/subscription/new?planCode=student-annual¤cy={{currencyCode}}", ng-click="signUpNowClicked('student')"
- ) #{translate("buy_now")}
.row.row-spaced(ng-cloak)
p.text-centered #{translate("choose_plan_works_for_you", {len:'{{trial_len}}'})}
diff --git a/services/web/app/views/subscriptions/successful_subscription.jade b/services/web/app/views/subscriptions/successful_subscription.jade
index 8413f5e036..17ac4f3594 100644
--- a/services/web/app/views/subscriptions/successful_subscription.jade
+++ b/services/web/app/views/subscriptions/successful_subscription.jade
@@ -2,7 +2,7 @@ extends ../layout
block content
.content.content-alt
- .container
+ .container(ng-controller="SuccessfulSubscriptionController")
.row
.col-md-8.col-md-offset-2
.card(ng-cloak)
diff --git a/services/web/app/views/user/settings.jade b/services/web/app/views/user/settings.jade
index d2fa8326d1..eb5bf671fa 100644
--- a/services/web/app/views/user/settings.jade
+++ b/services/web/app/views/user/settings.jade
@@ -150,16 +150,32 @@ block content
script(type='text/ng-template', id='deleteAccountModalTemplate')
.modal-header
h3 #{translate("delete_account")}
- .modal-body
- p !{translate("delete_account_warning_message_2")}
+ div.modal-body#delete-account-modal
+ p !{translate("delete_account_warning_message_3")}
form(novalidate, name="deleteAccountForm")
+ label #{translate('email')}
input.form-control(
type="text",
+ autocomplete="off",
placeholder="",
ng-model="state.deleteText",
focus-on="open",
ng-keyup="checkValidation()"
)
+ label #{translate('password')}
+ input.form-control(
+ type="password",
+ autocomplete="off",
+ placeholder="",
+ ng-model="state.password",
+ ng-keyup="checkValidation()"
+ )
+ div(ng-if="state.error")
+ div.alert.alert-danger
+ | #{translate('generic_something_went_wrong')}
+ div(ng-if="state.invalidCredentials")
+ div.alert.alert-danger
+ | #{translate('email_or_password_wrong_try_again')}
.modal-footer
button.btn.btn-default(
ng-click="cancel()"
diff --git a/services/web/package.json b/services/web/package.json
index 449039dcd2..cca2733643 100644
--- a/services/web/package.json
+++ b/services/web/package.json
@@ -35,7 +35,7 @@
"lynx": "0.1.1",
"marked": "^0.3.5",
"method-override": "^2.3.3",
- "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.3.0",
+ "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.6.0",
"mimelib": "0.2.14",
"mocha": "1.17.1",
"mongojs": "0.18.2",
diff --git a/services/web/public/coffee/ide.coffee b/services/web/public/coffee/ide.coffee
index 83ef177a92..04fda70d33 100644
--- a/services/web/public/coffee/ide.coffee
+++ b/services/web/public/coffee/ide.coffee
@@ -69,6 +69,12 @@ define [
reviewPanelOpen: false
}
$scope.user = window.user
+
+
+ $scope.shouldABTestPlans = false
+ if $scope.user.signUpDate >= '2016-10-27'
+ $scope.shouldABTestPlans = true
+
$scope.settings = window.userSettings
$scope.anonymous = window.anonymous
@@ -81,7 +87,7 @@ define [
# Only run the header AB test for newly registered users.
_abTestStartDate = new Date(Date.UTC(2016, 8, 28))
_userSignUpDate = new Date(window.user.signUpDate)
-
+
$scope.shouldABTestHeaderLabels = _userSignUpDate > _abTestStartDate
$scope.headerLabelsABVariant = ""
@@ -98,7 +104,7 @@ define [
# Tracking code.
$scope.$watch "ui.view", (newView, oldView) ->
if newView? and newView != "editor" and newView != "pdf"
- event_tracking.sendMBOnce "ide-open-view-#{ newView }-once"
+ event_tracking.sendMBOnce "ide-open-view-#{ newView }-once"
$scope.$watch "ui.chatOpen", (isOpen) ->
event_tracking.sendMBOnce "ide-open-chat-once" if isOpen
@@ -111,7 +117,7 @@ define [
# End of tracking code.
window._ide = ide
-
+
ide.validFileRegex = '^[^\*\/]*$' # Don't allow * and /
ide.project_id = $scope.project_id = window.project_id
diff --git a/services/web/public/coffee/ide/connection/ConnectionManager.coffee b/services/web/public/coffee/ide/connection/ConnectionManager.coffee
index f3d14a3e3d..811587e5ad 100644
--- a/services/web/public/coffee/ide/connection/ConnectionManager.coffee
+++ b/services/web/public/coffee/ide/connection/ConnectionManager.coffee
@@ -27,6 +27,7 @@ define [], () ->
@connected = false
@userIsInactive = false
+ @gracefullyReconnecting = false
@$scope.connection =
reconnecting: false
@@ -54,6 +55,7 @@ define [], () ->
@ide.socket.on "connect", () =>
sl_console.log "[socket.io connect] Connected"
@connected = true
+ @gracefullyReconnecting = false
@ide.pushEvent("connected")
@$scope.$apply () =>
@@ -81,7 +83,7 @@ define [], () ->
@$scope.$apply () =>
@$scope.connection.reconnecting = false
- if !$scope.connection.forced_disconnect and !@userIsInactive
+ if !$scope.connection.forced_disconnect and !@userIsInactive and !@gracefullyReconnecting
@startAutoReconnectCountdown()
@ide.socket.on 'forceDisconnect', (message) =>
@@ -97,7 +99,11 @@ define [], () ->
setTimeout () ->
location.reload()
, 10 * 1000
-
+
+ @ide.socket.on "reconnectGracefully", () =>
+ sl_console.log "Reconnect gracefully"
+ @reconnectGracefully()
+
joinProject: () ->
sl_console.log "[joinProject] joining..."
@ide.socket.emit 'joinProject', {
@@ -180,3 +186,24 @@ define [], () ->
@$scope.$apply () =>
@$scope.connection.inactive_disconnect = true
+ RECONNECT_GRACEFULLY_RETRY_INTERVAL: 5000 # ms
+ MAX_RECONNECT_GRACEFULLY_INTERVAL: 60 * 5 * 1000 # 5 minutes
+ reconnectGracefully: () ->
+ @reconnectGracefullyStarted ?= new Date()
+ userIsInactive = (new Date() - @lastUserAction) > @RECONNECT_GRACEFULLY_RETRY_INTERVAL
+ maxIntervalReached = (new Date() - @reconnectGracefullyStarted) > @MAX_RECONNECT_GRACEFULLY_INTERVAL
+ if userIsInactive or maxIntervalReached
+ sl_console.log "[reconnectGracefully] User didn't do anything for last 5 seconds, reconnecting"
+ @_reconnectGracefullyNow()
+ else
+ sl_console.log "[reconnectGracefully] User is working, will try again in 5 seconds"
+ setTimeout () =>
+ @reconnectGracefully()
+ , @RECONNECT_GRACEFULLY_RETRY_INTERVAL
+
+ _reconnectGracefullyNow: () ->
+ @gracefullyReconnecting = true
+ @reconnectGracefullyStarted = null
+ # Clear cookie so we don't go to the same backend server
+ $.cookie("SERVERID", "", { expires: -1, path: "/" })
+ @reconnectImmediately()
\ No newline at end of file
diff --git a/services/web/public/coffee/ide/editor/EditorManager.coffee b/services/web/public/coffee/ide/editor/EditorManager.coffee
index 9c6a124f1a..698604c9c7 100644
--- a/services/web/public/coffee/ide/editor/EditorManager.coffee
+++ b/services/web/public/coffee/ide/editor/EditorManager.coffee
@@ -8,11 +8,12 @@ define [
@$scope.editor = {
sharejs_doc: null
open_doc_id: null
+ open_doc_name: null
opening: true
}
@$scope.$on "entity:selected", (event, entity) =>
- if (@$scope.ui.view != "track-changes" and entity.type == "doc")
+ if (@$scope.ui.view != "history" and entity.type == "doc")
@openDoc(entity)
@$scope.$on "entity:deleted", (event, entity) =>
@@ -59,6 +60,7 @@ define [
return
@$scope.editor.open_doc_id = doc.id
+ @$scope.editor.open_doc_name = doc.name
@ide.localStorage "doc.open_id.#{@$scope.project_id}", doc.id
@ide.fileTreeManager.selectEntity(doc)
diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee
index 0ba4f269e3..a59d27bf95 100644
--- a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee
+++ b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee
@@ -2,20 +2,26 @@ define [
"base"
"ace/ace"
"ace/ext-searchbox"
+ "ace/ext-modelist"
"ide/editor/directives/aceEditor/undo/UndoManager"
"ide/editor/directives/aceEditor/auto-complete/AutoCompleteManager"
"ide/editor/directives/aceEditor/spell-check/SpellCheckManager"
"ide/editor/directives/aceEditor/highlights/HighlightsManager"
"ide/editor/directives/aceEditor/cursor-position/CursorPositionManager"
"ide/editor/directives/aceEditor/track-changes/TrackChangesManager"
-], (App, Ace, SearchBox, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager, TrackChangesManager) ->
+], (App, Ace, SearchBox, ModeList, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager, TrackChangesManager) ->
EditSession = ace.require('ace/edit_session').EditSession
+ ModeList = ace.require('ace/ext/modelist')
# set the path for ace workers if using a CDN (from editor.jade)
if window.aceWorkerPath != ""
+ syntaxValidationEnabled = true
ace.config.set('workerPath', "#{window.aceWorkerPath}")
else
- ace.config.setDefaultValue("session", "useWorker", false)
+ syntaxValidationEnabled = false
+
+ # By default, don't use workers - enable them per-session as required
+ ace.config.setDefaultValue("session", "useWorker", false)
# Ace loads its script itself, so we need to hook in to be able to clear
# the cache.
@@ -43,6 +49,7 @@ define [
readOnly: "="
annotations: "="
navigateHighlights: "="
+ fileName: "="
onCtrlEnter: "="
syntaxValidation: "="
reviewPanel: "="
@@ -62,6 +69,11 @@ define [
editor = ace.edit(element.find(".ace-editor-body")[0])
editor.$blockScrolling = Infinity
+
+ # disable auto insertion of brackets and quotes
+ editor.setOption('behavioursEnabled', false)
+ editor.setOption('wrapBehavioursEnabled', false)
+
window.editors ||= []
window.editors.push editor
@@ -198,16 +210,15 @@ define [
editor.setReadOnly !!value
scope.$watch "syntaxValidation", (value) ->
- session = editor.getSession()
- session.setOption("useWorker", value);
+ # ignore undefined settings here
+ # only instances of ace with an explicit value should set useWorker
+ # the history instance will have syntaxValidation undefined
+ if value? and syntaxValidationEnabled
+ session = editor.getSession()
+ session.setOption("useWorker", value);
editor.setOption("scrollPastEnd", true)
- resetSession = () ->
- session = editor.getSession()
- session.setUseWrapMode(true)
- session.setMode("ace/mode/latex")
-
updateCount = 0
onChange = () ->
updateCount++
@@ -229,9 +240,36 @@ define [
session = editor.getSession()
if session?
session.destroy()
- editor.setSession(new EditSession(lines, "ace/mode/latex"))
- resetSession()
- session = editor.getSession()
+
+ # see if we can lookup a suitable mode from ace
+ # but fall back to text by default
+ try
+ if scope.fileName.match(/\.(Rtex|bbl)$/i)
+ # recognise Rtex and bbl as latex
+ mode = "ace/mode/latex"
+ else if scope.fileName.match(/\.(sty|cls|clo)$/)
+ # recognise some common files as tex
+ mode = "ace/mode/tex"
+ else
+ mode = ModeList.getModeForPath(scope.fileName).mode
+ # we prefer plain_text mode over text mode because ace's
+ # text mode is actually for code and has unwanted
+ # indenting (see wrapMethod in ace edit_session.js)
+ if mode is "ace/mode/text"
+ mode = "ace/mode/plain_text"
+ catch
+ mode = "ace/mode/plain_text"
+
+ # create our new session
+ session = new EditSession(lines, mode)
+
+ session.setUseWrapMode(true)
+ # use syntax validation only when explicitly set
+ if scope.syntaxValidation? and syntaxValidationEnabled
+ session.setOption("useWorker", scope.syntaxValidation);
+
+ # now attach session to editor
+ editor.setSession(session)
doc = session.getDocument()
doc.on "change", onChange
diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor/undo/UndoManager.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor/undo/UndoManager.coffee
index 9c61ce983d..40f1ba7c82 100644
--- a/services/web/public/coffee/ide/editor/directives/aceEditor/undo/UndoManager.coffee
+++ b/services/web/public/coffee/ide/editor/directives/aceEditor/undo/UndoManager.coffee
@@ -233,8 +233,16 @@ define [
start = aceDelta.start
if !start?
error = new Error("aceDelta had no start event.")
+ JSONstringifyWithCycles = (o) ->
+ seen = []
+ return JSON.stringify o, (k,v) ->
+ if (typeof v == 'object')
+ if ( !seen.indexOf(v) )
+ return '__cycle__'
+ seen.push(v);
+ return v
Raven?.captureException(error, {
- aceDelta: JSON.stringify(aceDelta)
+ aceDelta: JSONstringifyWithCycles(aceDelta)
})
throw error
linesBefore = docLines.slice(0, start.row)
diff --git a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee
index 790f2384a1..c2559b1faf 100644
--- a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee
+++ b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee
@@ -29,12 +29,12 @@ define [
$scope.$watch "shouldShowLogs", (shouldShow) ->
if shouldShow
- $scope.$applyAsync () ->
+ $scope.$applyAsync () ->
$scope.shouldDropUp = getFilesDropdownTopCoordAsRatio() > 0.65
# log hints tracking
$scope.logHintsNegFeedbackValues = logHintsFeedback.feedbackOpts
-
+
$scope.trackLogHintsLearnMore = () ->
event_tracking.sendMB "logs-hints-learn-more"
@@ -108,7 +108,7 @@ define [
_csrf: window.csrfToken
}, {params: params}
- parseCompileResponse = (response) ->
+ parseCompileResponse = (response) ->
# keep last url
last_pdf_url = $scope.pdf.url
@@ -469,7 +469,7 @@ define [
event_tracking.sendMB "subscription-start-trial", { source }
- window.open("/user/subscription/new?planCode=student_free_trial_7_days")
+ window.open("/user/subscription/new?planCode=#{$scope.startTrialPlanCode}")
$scope.startedFreeTrial = true
App.factory "synctex", ["ide", "$http", "$q", (ide, $http, $q) ->
diff --git a/services/web/public/coffee/ide/pdfng/directives/pdfRenderer.coffee b/services/web/public/coffee/ide/pdfng/directives/pdfRenderer.coffee
index e0b6da3659..254db63d08 100644
--- a/services/web/public/coffee/ide/pdfng/directives/pdfRenderer.coffee
+++ b/services/web/public/coffee/ide/pdfng/directives/pdfRenderer.coffee
@@ -30,6 +30,10 @@ define [
TEXTLAYER_TIMEOUT: 100
constructor: (@url, @options) ->
+ # set up external character mappings - needed for Japanese etc
+ window.PDFJS.cMapUrl = './bcmaps/'
+ window.PDFJS.cMapPacked = true
+
if window.location?.search?.indexOf("disable-font-face=true") >= 0
window.PDFJS.disableFontFace = true
else
diff --git a/services/web/public/coffee/ide/references/ReferencesManager.coffee b/services/web/public/coffee/ide/references/ReferencesManager.coffee
index 2f1e95c5b1..c5d7c2348b 100644
--- a/services/web/public/coffee/ide/references/ReferencesManager.coffee
+++ b/services/web/public/coffee/ide/references/ReferencesManager.coffee
@@ -17,8 +17,13 @@ define [
# When we join the project:
# index all references files
# and don't broadcast to all clients
+ @inited = false
@$scope.$on 'project:joined', (e) =>
- @indexAllReferences(false)
+ # We only need to grab the references when the editor first loads,
+ # not on every reconnect
+ if !@inited
+ @inited = true
+ @indexAllReferences(false)
setTimeout(
(self) ->
diff --git a/services/web/public/coffee/ide/settings/controllers/SettingsController.coffee b/services/web/public/coffee/ide/settings/controllers/SettingsController.coffee
index 29bc8e979c..bde479991b 100644
--- a/services/web/public/coffee/ide/settings/controllers/SettingsController.coffee
+++ b/services/web/public/coffee/ide/settings/controllers/SettingsController.coffee
@@ -30,7 +30,7 @@ define [
$scope.$watch "settings.syntaxValidation", (syntaxValidation, oldSyntaxValidation) =>
if syntaxValidation != oldSyntaxValidation
- settings.saveProjectSettings({syntaxValidation: syntaxValidation})
+ settings.saveSettings({syntaxValidation: syntaxValidation})
$scope.$watch "project.spellCheckLanguage", (language, oldLanguage) =>
return if @ignoreUpdates
diff --git a/services/web/public/coffee/main/account-settings.coffee b/services/web/public/coffee/main/account-settings.coffee
index 29ec146051..08226ab399 100644
--- a/services/web/public/coffee/main/account-settings.coffee
+++ b/services/web/public/coffee/main/account-settings.coffee
@@ -29,10 +29,13 @@ define [
App.controller "DeleteAccountModalController", [
"$scope", "$modalInstance", "$timeout", "$http",
($scope, $modalInstance, $timeout, $http) ->
- $scope.state =
+ $scope.state =
isValid : false
deleteText: ""
+ password: ""
inflight: false
+ error: false
+ invalidCredentials: false
$modalInstance.opened.then () ->
$timeout () ->
@@ -40,20 +43,33 @@ define [
, 700
$scope.checkValidation = ->
- $scope.state.isValid = $scope.state.deleteText == $scope.email
+ $scope.state.isValid = $scope.state.deleteText == $scope.email and $scope.state.password.length > 0
$scope.delete = () ->
$scope.state.inflight = true
-
+ $scope.state.error = false
+ $scope.state.invalidCredentials = false
$http({
- method: "DELETE"
- url: "/user"
+ method: "POST"
+ url: "/user/delete"
headers:
"X-CSRF-Token": window.csrfToken
+ "Content-Type": 'application/json'
+ data:
+ password: $scope.state.password
})
.success () ->
$modalInstance.close()
+ $scope.state.inflight = false
+ $scope.state.error = false
+ $scope.state.invalidCredentials = false
window.location = "/"
+ .error (data, status) ->
+ $scope.state.inflight = false
+ if status == 403
+ $scope.state.invalidCredentials = true
+ else
+ $scope.state.error = true
$scope.cancel = () ->
$modalInstance.dismiss('cancel')
diff --git a/services/web/public/coffee/main/account-upgrade.coffee b/services/web/public/coffee/main/account-upgrade.coffee
index be842b6907..6144bea9ef 100644
--- a/services/web/public/coffee/main/account-upgrade.coffee
+++ b/services/web/public/coffee/main/account-upgrade.coffee
@@ -6,14 +6,34 @@ define [
$scope.buttonClass = "btn-primary"
$scope.startFreeTrial = (source, couponCode) ->
- event_tracking.sendMB "subscription-start-trial", { source }
+ plan = 'collaborator_free_trial_7_days'
w = window.open()
- sixpack.convert "track-changes-discount", ->
- sixpack.participate 'in-editor-free-trial-plan', ['student', 'collaborator'], (planName, rawResponse)->
- ga?('send', 'event', 'subscription-funnel', 'upgraded-free-trial', source)
- url = "/user/subscription/new?planCode=#{planName}_free_trial_7_days&ssp=#{planName == 'collaborator'}"
- if couponCode?
- url = "#{url}&cc=#{couponCode}"
- $scope.startedFreeTrial = true
- w.location = url
+ go = () ->
+ ga?('send', 'event', 'subscription-funnel', 'upgraded-free-trial', source)
+ url = "/user/subscription/new?planCode=#{plan}&ssp=true"
+ if couponCode?
+ url = "#{url}&cc=#{couponCode}"
+ $scope.startedFreeTrial = true
+
+ switch source
+ when "dropbox"
+ sixpack.participate 'teaser-dropbox-text', ['default', 'dropbox-focused'], (variant) ->
+ event_tracking.sendMB "subscription-start-trial", { source, plan, variant }
+
+ when "history"
+ sixpack.participate 'teaser-history', ['default', 'focused'], (variant) ->
+ event_tracking.sendMB "subscription-start-trial", { source, plan, variant }
+
+ else
+ event_tracking.sendMB "subscription-start-trial", { source, plan }
+
+ w.location = url
+
+ if $scope.shouldABTestPlans
+ sixpack.participate 'plans-1610', ['default', 'heron', 'ibis'], (chosenVariation, rawResponse)->
+ if chosenVariation in ['heron', 'ibis']
+ plan = "collaborator_#{chosenVariation}"
+ go()
+ else
+ go()
diff --git a/services/web/public/coffee/main/new-subscription.coffee b/services/web/public/coffee/main/new-subscription.coffee
index d006c6173c..61961cfccb 100644
--- a/services/web/public/coffee/main/new-subscription.coffee
+++ b/services/web/public/coffee/main/new-subscription.coffee
@@ -5,12 +5,15 @@ define [
App.controller "NewSubscriptionController", ($scope, MultiCurrencyPricing, abTestManager, $http, sixpack, event_tracking, ccUtils)->
throw new Error("Recurly API Library Missing.") if typeof recurly is "undefined"
-
+
$scope.currencyCode = MultiCurrencyPricing.currencyCode
$scope.plans = MultiCurrencyPricing.plans
$scope.switchToStudent = ()->
- window.location = "/user/subscription/new?planCode=student_free_trial_7_days¤cy=#{$scope.currencyCode}&cc=#{$scope.data.coupon}"
+ currentPlanCode = window.plan_code
+ planCode = currentPlanCode.replace('collaborator', 'student')
+ event_tracking.sendMB 'subscription-form-switch-to-student', { plan: window.plan_code }
+ window.location = "/user/subscription/new?planCode=#{planCode}¤cy=#{$scope.currencyCode}&cc=#{$scope.data.coupon}"
event_tracking.sendMB "subscription-form", { plan : window.plan_code }
diff --git a/services/web/public/coffee/main/plans.coffee b/services/web/public/coffee/main/plans.coffee
index 4f21c4b5a8..538152bf43 100644
--- a/services/web/public/coffee/main/plans.coffee
+++ b/services/web/public/coffee/main/plans.coffee
@@ -5,12 +5,171 @@ define [
App.factory "MultiCurrencyPricing", () ->
-
+
currencyCode = window.recomendedCurrency
return {
currencyCode:currencyCode
- plans:
+
+ heron:
+ USD:
+ student:
+ monthly: "$6"
+ annual: "$60"
+ collaborator:
+ monthly: "$12"
+ annual: "$144"
+ EUR:
+ student:
+ monthly: "€5"
+ annual: "€50"
+ collaborator:
+ monthly: "€11"
+ annual: "€132"
+ GBP:
+ student:
+ monthly: "£5"
+ annual: "£50"
+ collaborator:
+ monthly: "£10"
+ annual: "£120"
+ SEK:
+ student:
+ monthly: "45 kr"
+ annual: "450 kr"
+ collaborator:
+ monthly: "90 kr"
+ annual: "1080 kr"
+ CAD:
+ student:
+ monthly: "$7"
+ annual: "$70"
+ collaborator:
+ monthly: "$14"
+ annual: "$168"
+ NOK:
+ student:
+ monthly: "45 kr"
+ annual: "450 kr"
+ collaborator:
+ monthly: "90 kr"
+ annual: "1080 kr"
+ DKK:
+ student:
+ monthly: "40 kr"
+ annual: "400 kr"
+ collaborator:
+ monthly: "70 kr"
+ annual: "840 kr"
+ AUD:
+ student:
+ monthly: "$8"
+ annual: "$80"
+ collaborator:
+ monthly: "$15"
+ annual: "$180"
+ NZD:
+ student:
+ monthly: "$8"
+ annual: "$80"
+ collaborator:
+ monthly: "$15"
+ annual: "$180"
+ CHF:
+ student:
+ monthly: "Fr 6"
+ annual: "Fr 60"
+ collaborator:
+ monthly: "Fr 12"
+ annual: "Fr 144"
+ SGD:
+ student:
+ monthly: "$8"
+ annual: "$80"
+ collaborator:
+ monthly: "$16"
+ annual: "$192"
+
+ ibis:
+ USD:
+ student:
+ monthly: "$10"
+ annual: "$100"
+ collaborator:
+ monthly: "$18"
+ annual: "$216"
+ EUR:
+ student:
+ monthly: "€9"
+ annual: "€90"
+ collaborator:
+ monthly: "€17"
+ annual: "€204"
+ GBP:
+ student:
+ monthly: "£7"
+ annual: "£70"
+ collaborator:
+ monthly: "£14"
+ annual: "£168"
+ SEK:
+ student:
+ monthly: "75 kr"
+ annual: "750 kr"
+ collaborator:
+ monthly: "140 kr"
+ annual: "1680 kr"
+ CAD:
+ student:
+ monthly: "$12"
+ annual: "$120"
+ collaborator:
+ monthly: "$22"
+ annual: "$264"
+ NOK:
+ student:
+ monthly: "75 kr"
+ annual: "750 kr"
+ collaborator:
+ monthly: "140 kr"
+ annual: "1680 kr"
+ DKK:
+ student:
+ monthly: "68 kr"
+ annual: "680 kr"
+ collaborator:
+ monthly: "110 kr"
+ annual: "1320 kr"
+ AUD:
+ student:
+ monthly: "$13"
+ annual: "$130"
+ collaborator:
+ monthly: "$22"
+ annual: "$264"
+ NZD:
+ student:
+ monthly: "$14"
+ annual: "$140"
+ collaborator:
+ monthly: "$22"
+ annual: "$264"
+ CHF:
+ student:
+ monthly: "Fr 10"
+ annual: "Fr 100"
+ collaborator:
+ monthly: "Fr 18"
+ annual: "Fr 216"
+ SGD:
+ student:
+ monthly: "$14"
+ annual: "$140"
+ collaborator:
+ monthly: "$25"
+ annual: "$300"
+
+ plans:
USD:
symbol: "$"
student:
@@ -23,7 +182,7 @@ define [
monthly: "$30"
annual: "$360"
- EUR:
+ EUR:
symbol: "€"
student:
monthly: "€7"
@@ -34,7 +193,7 @@ define [
professional:
monthly: "€28"
annual: "€336"
-
+
GBP:
symbol: "£"
student:
@@ -117,7 +276,7 @@ define [
professional:
monthly: "$35"
annual: "$420"
-
+
CHF:
symbol: "Fr"
student:
@@ -141,36 +300,54 @@ define [
professional:
monthly: "$40"
annual: "$480"
+
}
-
+ App.controller "PlansController", ($scope, $modal, event_tracking, abTestManager, MultiCurrencyPricing, $http, sixpack) ->
- App.controller "PlansController", ($scope, $modal, event_tracking, abTestManager, MultiCurrencyPricing, $http) ->
+ $scope.showPlans = false
+
+ $scope.plansVariant = 'default'
+ $scope.shouldABTestPlans = window.shouldABTestPlans
+
+ if $scope.shouldABTestPlans
+ sixpack.participate 'plans-1610', ['default', 'heron', 'ibis'], (chosenVariation, rawResponse)->
+ $scope.plansVariant = chosenVariation
+ event_tracking.sendMB 'plans-page', {plans_variant: chosenVariation}
+ if chosenVariation in ['heron', 'ibis']
+ # overwrite student plans with alternative
+ for currency, _v of $scope.plans
+ $scope.plans[currency]['student'] = MultiCurrencyPricing[chosenVariation][currency]['student']
+ $scope.plans[currency]['collaborator'] = MultiCurrencyPricing[chosenVariation][currency]['collaborator']
+ $scope.showPlans = true
+ else
+ $scope.showPlans = true
$scope.plans = MultiCurrencyPricing.plans
+
$scope.currencyCode = MultiCurrencyPricing.currencyCode
$scope.trial_len = 7
+
$scope.planQueryString = '_free_trial_7_days'
$scope.ui =
view: "monthly"
-
$scope.changeCurreny = (newCurrency)->
$scope.currencyCode = newCurrency
$scope.signUpNowClicked = (plan, annual)->
+ event_tracking.sendMB 'plans-page-start-trial', {plan}
if $scope.ui.view == "annual"
plan = "#{plan}_annual"
-
- event_tracking.send 'subscription-funnel', 'sign_up_now_button', plan
+ event_tracking.send 'subscription-funnel', 'sign_up_now_button', plan
$scope.switchToMonthly = ->
$scope.ui.view = "monthly"
event_tracking.send 'subscription-funnel', 'plans-page', 'monthly-prices'
-
+
$scope.switchToStudent = ->
$scope.ui.view = "student"
event_tracking.send 'subscription-funnel', 'plans-page', 'student-prices'
@@ -178,7 +355,7 @@ define [
$scope.switchToAnnual = ->
$scope.ui.view = "annual"
event_tracking.send 'subscription-funnel', 'plans-page', 'student-prices'
-
+
$scope.openGroupPlanModal = () ->
$modal.open {
templateUrl: "groupPlanModalTemplate"
diff --git a/services/web/public/coffee/main/subscription-dashboard.coffee b/services/web/public/coffee/main/subscription-dashboard.coffee
index 7476d814e1..71bc198e6d 100644
--- a/services/web/public/coffee/main/subscription-dashboard.coffee
+++ b/services/web/public/coffee/main/subscription-dashboard.coffee
@@ -1,15 +1,21 @@
define [
"base"
], (App)->
+
+ App.controller 'SuccessfulSubscriptionController', ($scope, sixpack) ->
+ sixpack.convert 'plans-1610', () ->
+
+
SUBSCRIPTION_URL = "/user/subscription/update"
setupReturly = _.once ->
recurly?.configure window.recurlyApiKey
PRICES = {}
+
App.controller "CurrenyDropdownController", ($scope, MultiCurrencyPricing, $q)->
- $scope.plans = MultiCurrencyPricing.plans
+ # $scope.plans = MultiCurrencyPricing.plans
$scope.currencyCode = MultiCurrencyPricing.currencyCode
$scope.changeCurrency = (newCurrency)->
@@ -31,7 +37,7 @@ define [
$scope.currencyCode = MultiCurrencyPricing.currencyCode
$scope.pricing = MultiCurrencyPricing
- $scope.plans = MultiCurrencyPricing.plans
+ # $scope.plans = MultiCurrencyPricing.plans
$scope.currencySymbol = MultiCurrencyPricing.plans[MultiCurrencyPricing.currencyCode].symbol
$scope.currencyCode = MultiCurrencyPricing.currencyCode
@@ -53,9 +59,9 @@ define [
price = ""
App.controller "ConfirmChangePlanController", ($scope, $modalInstance, $http)->
-
+
$scope.confirmChangePlan = ->
- body =
+ body =
plan_code: $scope.plan.planCode
_csrf : window.csrfToken
@@ -74,7 +80,7 @@ define [
$scope.confirmLeaveGroup = ->
$scope.inflight = true
$http({
- url: "/subscription/group/user",
+ url: "/subscription/group/user",
method: "DELETE",
params: {admin_user_id: $scope.admin_id, _csrf: window.csrfToken}
}).success ->
@@ -87,6 +93,8 @@ define [
App.controller "UserSubscriptionController", ($scope, MultiCurrencyPricing, $http, sixpack, $modal) ->
+ $scope.plans = MultiCurrencyPricing.plans
+
freeTrialEndDate = new Date(subscription?.trial_ends_at)
sevenDaysTime = new Date()
@@ -96,6 +104,16 @@ define [
freeTrialExpiresUnderSevenDays = freeTrialEndDate < sevenDaysTime
$scope.view = 'overview'
+ $scope.getSuffix = (planCode) ->
+ planCode?.match(/(.*?)_(.*)/)?[2] || null
+ $scope.subscriptionSuffix = $scope.getSuffix(window?.subscription?.planCode)
+ if $scope.subscriptionSuffix == 'free_trial_7_days'
+ $scope.subscriptionSuffix = ''
+ $scope.isNextGenPlan = $scope.subscriptionSuffix in ['heron', 'ibis']
+
+ $scope.shouldShowPlan = (planCode) ->
+ $scope.getSuffix(planCode) not in ['heron', 'ibis']
+
isMonthlyCollab = subscription?.planCode?.indexOf("collaborator") != -1 and subscription?.planCode?.indexOf("ann") == -1
stillInFreeTrial = freeTrialInFuture and freeTrialExpiresUnderSevenDays
@@ -118,7 +136,7 @@ define [
$scope.studentPrice = $scope.currencySymbol + (totalPriceExTax + taxAmmount)
$scope.downgradeToStudent = ->
- body =
+ body =
plan_code: 'student'
_csrf : window.csrfToken
$scope.inflight = true
@@ -129,7 +147,7 @@ define [
console.log "something went wrong changing plan"
$scope.cancelSubscription = ->
- body =
+ body =
_csrf : window.csrfToken
$scope.inflight = true
@@ -158,7 +176,7 @@ define [
$scope.exendTrial = ->
- body =
+ body =
_csrf : window.csrfToken
$scope.inflight = true
$http.put("/user/subscription/extend", body)
@@ -166,6 +184,3 @@ define [
location.reload()
.error ->
console.log "something went wrong changing plan"
-
-
-
diff --git a/services/web/public/img/teasers/history/teaser-history.png b/services/web/public/img/teasers/history/teaser-history.png
new file mode 100644
index 0000000000..d03671f1f1
Binary files /dev/null and b/services/web/public/img/teasers/history/teaser-history.png differ
diff --git a/services/web/public/js/ace-1.2.5/mode-latex.js b/services/web/public/js/ace-1.2.5/mode-latex.js
index 5516f2a152..f183d7c263 100644
--- a/services/web/public/js/ace-1.2.5/mode-latex.js
+++ b/services/web/public/js/ace-1.2.5/mode-latex.js
@@ -205,128 +205,157 @@ var LatexFoldMode = require("./folding/latex").FoldMode;
var Range = require("../range").Range;
var WorkerClient = require("ace/worker/worker_client").WorkerClient;
+var createLatexWorker = function (session) {
+ var doc = session.getDocument();
+ var selection = session.getSelection();
+ var cursorAnchor = selection.lead;
+
+ var savedRange = {};
+ var suppressions = [];
+ var hints = [];
+ var changeHandler = null;
+ var docChangePending = false;
+ var firstPass = true;
+
+ var worker = new WorkerClient(["ace"], "ace/mode/latex_worker", "LatexWorker");
+ worker.attachToDocument(doc);
+ var docChangeHandler = doc.on("change", function () {
+ docChangePending = true;
+ if(changeHandler) {
+ clearTimeout(changeHandler);
+ changeHandler = null;
+ }
+ });
+
+ var cursorHandler = selection.on("changeCursor", function () {
+ if (docChangePending) { return; } ;
+ changeHandler = setTimeout(function () {
+ updateMarkers({cursorMoveOnly:true});
+ suppressions = [];
+ changeHandler = null;
+ }, 100);
+ });
+
+ var updateMarkers = function (options) {
+ if (!options) { options = {};};
+ var cursorMoveOnly = options.cursorMoveOnly;
+ var annotations = [];
+ var newRange = {};
+ var cursor = selection.getCursor();
+ suppressions = [];
+
+ for (var i = 0, len = hints.length; i 0) {
+ var originalAnnotations = session.getAnnotations();
+ session.setAnnotations(originalAnnotations.concat(annotations));
+ };
+ firstPass = false;
+ } else {
+ session.setAnnotations(annotations);
+ }
+ };
+
+ };
+ worker.on("lint", function(results) {
+ if(docChangePending) { docChangePending = false; };
+ hints = results.data;
+ if (hints.length > 100) {
+ hints = hints.slice(0, 100); // limit to 100 errors
+ };
+ updateMarkers();
+ });
+ worker.on("terminate", function() {
+ if(changeHandler) {
+ clearTimeout(changeHandler);
+ changeHandler = null;
+ }
+ doc.off("change", docChangeHandler);
+ selection.off("changeCursor", cursorHandler);
+ for (var key in savedRange) {
+ var range = savedRange[key];
+ if (range.start !== cursorAnchor) { range.start.detach(); }
+ if (range.end !== cursorAnchor) { range.end.detach(); }
+ session.removeMarker(range.id);
+ }
+ savedRange = {};
+ hints = [];
+ suppressions = [];
+ session.clearAnnotations();
+ });
+
+ return worker;
+};
var Mode = function() {
this.HighlightRules = LatexHighlightRules;
this.foldingRules = new LatexFoldMode();
- this.createWorker = function(session) {
- var doc = session.getDocument();
- var selection = session.getSelection();
-
- var savedRange = {};
- var suppressions = [];
- var hints = [];
- var changeHandler = null;
-
- var worker = new WorkerClient(["ace"], "ace/mode/latex_worker", "LatexWorker");
- worker.attachToDocument(doc);
-
- doc.on("change", function () {
- if(changeHandler) {
- clearTimeout(changeHandler);
- changeHandler = null;
- }
- });
-
- selection.on("changeCursor", function () {
- if(suppressions.length > 0) {
- changeHandler = setTimeout(function () {
- updateMarkers();
- suppressions = [];
- changeHandler = null;
- }, 100);
- }
- });
-
- var updateMarkers = function () {
- var annotations = [];
- var newRange = {};
- var cursor = selection.getCursor();
- suppressions = [];
-
- for (var i = 0; i= fromCol && start_row === toRow && start_col <= toCol) {
- suppress = true;
- break;
- }
- }
- if(suppress) { continue; };
-
- var key = "(" + start_row + "," + start_col + ")" + ":" + "(" + end_row + "," + end_col + ")";
- newRange[key] = data;
- annotations.push(data);
- }
-
- var newKeys = Object.keys(newRange);
- var oldKeys = Object.keys(savedRange);
- var changes = 0;
- for (i = 0; i < newKeys.length; i++) {
- key = newKeys[i];
- if (!savedRange[key]) {
- var new_range = newRange[key];
- var a = doc.createAnchor(new_range.start_row, new_range.start_col);
- var b = doc.createAnchor(new_range.end_row, new_range.end_col);
- var range = new Range();
- range.start = a;
- range.end = b;
- range.id = session.addMarker(range, "ace_error-marker", "text");
- savedRange[key] = range;
- changes++;
- }
- }
-
- for (i = 0; i < oldKeys.length; i++) {
- key = oldKeys[i];
- if (!newRange[key]) {
- range = savedRange[key];
- range.start.detach();
- range.end.detach();
- session.removeMarker(range.id);
- delete savedRange[key];
- changes++;
- }
- }
-
- if (changes>0) {
- session.setAnnotations(annotations);
- };
- };
-
- worker.on("lint", function(results) {
- hints = results.data;
- if (hints.length > 100) {
- hints = hints.slice(0, 100); // limit to 100 errors
- };
- updateMarkers();
- });
-
- worker.on("terminate", function() {
- var oldKeys = Object.keys(savedRange);
- for (var i = 0; i < oldKeys.length; i++) {
- var key = oldKeys[i];
- var range = savedRange[key];
- session.removeMarker(range.id);
- delete savedRange[key];
- }
-
- });
- return worker;
- };
+ this.createWorker = createLatexWorker;
};
oop.inherits(Mode, TextMode);
diff --git a/services/web/public/js/ace-1.2.5/worker-latex.js b/services/web/public/js/ace-1.2.5/worker-latex.js
index d90bb8043b..20c377dc83 100644
--- a/services/web/public/js/ace-1.2.5/worker-latex.js
+++ b/services/web/public/js/ace-1.2.5/worker-latex.js
@@ -1419,407 +1419,634 @@ var LatexWorker = exports.LatexWorker = function(sender) {
oop.inherits(LatexWorker, Mirror);
-var Parse = function (text) {
- var errors = [];
- var Comments = [];
+var Tokenise = function (text) {
var Tokens = [];
- var Environments = [];
+ var Comments = [];
var pos = -1;
- var SPECIAL = /[\\\{\}\$\&\#\^\_\~\%]/g;
- var CS = /[^a-zA-Z]/g;
+ var SPECIAL = /[\\\{\}\$\&\#\^\_\~\%]/g; // match TeX special characters
+ var NEXTCS = /[^a-zA-Z]/g; // match characters which aren't part of a TeX control sequence
var idx = 0;
- var lineNumber = 0;
- var linePosition = [];
+
+ var lineNumber = 0; // current line number when parsing tokens (zero-based)
+ var linePosition = []; // mapping from line number to absolute offset of line in text[]
linePosition[0] = 0;
- var TokenError = function (token, message) {
- var line = token[0], type = token[1], start = token[2], end = token[3], seq = token[4];
- var start_col = start - linePosition[line];
- var end_col = end - linePosition[line] + 1;
- errors.push({row: line,
- column: start_col,
- start_row:line,
- start_col: start_col,
- end_row:line,
- end_col: end_col,
- type:"error",
- text:message,
- suppressIfEditing:true});
- };
-
- var TokenErrorFromTo = function (fromToken, toToken, message) {
- var fromLine = fromToken[0], fromStart = fromToken[2], fromEnd = fromToken[3];
- var toLine = toToken[0], toStart = toToken[2], toEnd = toToken[3];
- if (!toEnd) { toEnd = toStart + 1;};
- var start_col = fromStart - linePosition[fromLine];
- var end_col = toEnd - linePosition[toLine] + 1;
-
- errors.push({row: line,
- column: start_col,
- start_row: fromLine,
- start_col: start_col,
- end_row: toLine,
- end_col: end_col,
- type:"error",
- text:message,
- suppressIfEditing:true});
- };
-
-
- var EnvErrorFromTo = function (fromEnv, toEnv, message, options) {
- if(!options) { options = {} ; };
- var fromToken = fromEnv.token, toToken = toEnv.closeToken || toEnv.token;
- var fromLine = fromToken[0], fromStart = fromToken[2], fromEnd = fromToken[3], fromSeq = fromToken[4];
- if (!toToken) {toToken = fromToken;};
- var toLine = toToken[0], toStart = toToken[2], toEnd = toToken[3], toSeq = toToken[4];
- if (!toEnd) { toEnd = toStart + 1;};
- var start_col = fromStart - linePosition[fromLine];
- var end_col = toEnd - linePosition[toLine] + 1;
- errors.push({row:toLine,
- column:end_col,
- start_row:fromLine,
- start_col: start_col,
- end_row:toLine,
- end_col: end_col,
- type:"error",
- text:message,
- suppressIfEditing:options.suppressIfEditing});
- };
-
- var EnvErrorTo = function (toEnv, message) {
- var token = toEnv.closeToken || toEnv.token;
- var line = token[0], type = token[1], start = token[2], end = token[3], seq = token[4];
- if (!end) { end = start + 1; };
- var end_col = end - linePosition[line] + 1;
- var err = {row: line,
- column: end_col,
- start_row:0,
- start_col: 0,
- end_row: line,
- end_col: end_col,
- type:"error",
- text:message};
- errors.push(err);
- };
-
- var EnvErrorFrom = function (env, message) {
- var token = env.token;
- var line = token[0], type = token[1], start = token[2], end = token[3], seq = token[4];
- var start_col = start - linePosition[line];
- var end_col = Infinity;
- errors.push({row: line,
- column: start_col,
- start_row:line,
- start_col: start_col,
- end_row: lineNumber,
- end_col: end_col,
- type:"error",
- text:message});
- };
-
var checkingDisabled = false;
+ var count = 0; // number of tokens parses
+ var MAX_TOKENS = 100000;
while (true) {
- var result = SPECIAL.exec(text);
- if (result == null) {
- if (idx < text.length) {
- Tokens.push([lineNumber, "Text", idx, text.length]);
- }
- break;
- }
- if (result && result.index <= pos) {
- break;
- };
- pos = result.index;
- var newIdx = SPECIAL.lastIndex;
- if (pos > idx) {
- Tokens.push([lineNumber, "Text", idx, pos]);
- }
- for (var i = idx; i < pos; i++) {
- if (text[i] === "\n") {
- lineNumber++;
- linePosition[lineNumber] = i+1;
- }
- }
- idx = newIdx;
- var code = result[0];
- if (code === "%") {
- var newLinePos = text.indexOf("\n", idx);
- if (newLinePos === -1) {
- newLinePos = text.length;
- };
- var commentString = text.substring(idx, newLinePos);
- if (commentString.indexOf("%novalidate") === 0) {
- return [];
- } else if(!checkingDisabled && commentString.indexOf("%begin novalidate") === 0) {
- checkingDisabled = true;
- } else if (checkingDisabled && commentString.indexOf("%end novalidate") === 0) {
- checkingDisabled = false;
- };
- idx = SPECIAL.lastIndex = newLinePos + 1;
- Comments.push([lineNumber, idx, newLinePos]);
- lineNumber++;
- linePosition[lineNumber] = idx;
- } else if (checkingDisabled) {
- continue;
- } else if (code === '\\') {
- CS.lastIndex = idx;
- var controlSequence = CS.exec(text);
- var nextSpecialPos = controlSequence === null ? idx : controlSequence.index;
- if (nextSpecialPos === idx) {
- Tokens.push([lineNumber, code, pos, idx + 1, text[idx]]);
- idx = SPECIAL.lastIndex = idx + 1;
- char = text[nextSpecialPos];
- if (char === '\n') { lineNumber++; linePosition[lineNumber] = nextSpecialPos;};
- } else {
- Tokens.push([lineNumber, code, pos, nextSpecialPos, text.slice(idx, nextSpecialPos)]);
- var char;
- while ((char = text[nextSpecialPos]) === ' ' || char === '\t' || char === '\r' || char === '\n') {
- nextSpecialPos++;
- if (char === '\n') { lineNumber++; linePosition[lineNumber] = nextSpecialPos;};
- }
- idx = SPECIAL.lastIndex = nextSpecialPos;
- }
- } else if (code === "{") {
- Tokens.push([lineNumber, code, pos]);
- } else if (code === "}") {
- Tokens.push([lineNumber, code, pos]);
- } else if (code === "$") {
- if (text[idx] === "$") {
- idx = SPECIAL.lastIndex = idx + 1;
- Tokens.push([lineNumber, "$$", pos]);
- } else {
- Tokens.push([lineNumber, code, pos]);
- }
- } else if (code === "&") {
- Tokens.push([lineNumber, code, pos]);
- } else if (code === "#") {
- Tokens.push([lineNumber, code, pos]);
- } else if (code === "^") {
- Tokens.push([lineNumber, code, pos]);
- } else if (code === "_") {
- Tokens.push([lineNumber, code, pos]);
- } else if (code === "~") {
- Tokens.push([lineNumber, code, pos]);
- } else {
- throw "unrecognised character " + code;
- }
+ count++;
+ if (count > MAX_TOKENS) {
+ throw new Error("exceed max token count of " + MAX_TOKENS);
+ break;
+ };
+ var result = SPECIAL.exec(text);
+ if (result == null) {
+ if (idx < text.length) {
+ Tokens.push([lineNumber, "Text", idx, text.length]);
+ }
+ break;
+ }
+ if (result && result.index <= pos) {
+ throw new Error("infinite loop in parsing");
+ break;
+ };
+ pos = result.index;
+ if (pos > idx) {
+ Tokens.push([lineNumber, "Text", idx, pos]);
+ }
+ for (var i = idx; i < pos; i++) {
+ if (text[i] === "\n") {
+ lineNumber++;
+ linePosition[lineNumber] = i+1;
+ }
+ }
+
+ var newIdx = SPECIAL.lastIndex;
+ idx = newIdx;
+ var code = result[0];
+ if (code === "%") { // comment character
+ var newLinePos = text.indexOf("\n", idx);
+ if (newLinePos === -1) {
+ newLinePos = text.length;
+ };
+ var commentString = text.substring(idx, newLinePos);
+ if (commentString.indexOf("%novalidate") === 0) {
+ return [];
+ } else if(!checkingDisabled && commentString.indexOf("%begin novalidate") === 0) {
+ checkingDisabled = true;
+ } else if (checkingDisabled && commentString.indexOf("%end novalidate") === 0) {
+ checkingDisabled = false;
+ };
+ idx = SPECIAL.lastIndex = newLinePos + 1;
+ Comments.push([lineNumber, idx, newLinePos]);
+ lineNumber++;
+ linePosition[lineNumber] = idx;
+ } else if (checkingDisabled) {
+ continue;
+ } else if (code === '\\') { // escape character
+ NEXTCS.lastIndex = idx;
+ var controlSequence = NEXTCS.exec(text);
+ var nextSpecialPos = controlSequence === null ? idx : controlSequence.index;
+ if (nextSpecialPos === idx) {
+ Tokens.push([lineNumber, code, pos, idx + 1, text[idx]]);
+ idx = SPECIAL.lastIndex = idx + 1;
+ char = text[nextSpecialPos];
+ if (char === '\n') { lineNumber++; linePosition[lineNumber] = nextSpecialPos;};
+ } else {
+ Tokens.push([lineNumber, code, pos, nextSpecialPos, text.slice(idx, nextSpecialPos)]);
+ var char;
+ while ((char = text[nextSpecialPos]) === ' ' || char === '\t' || char === '\r' || char === '\n') {
+ nextSpecialPos++;
+ if (char === '\n') { lineNumber++; linePosition[lineNumber] = nextSpecialPos;};
+ }
+ idx = SPECIAL.lastIndex = nextSpecialPos;
+ }
+ } else if (code === "{") { // open group
+ Tokens.push([lineNumber, code, pos]);
+ } else if (code === "}") { // close group
+ Tokens.push([lineNumber, code, pos]);
+ } else if (code === "$") { // math mode
+ if (text[idx] === "$") {
+ idx = SPECIAL.lastIndex = idx + 1;
+ Tokens.push([lineNumber, "$$", pos]);
+ } else {
+ Tokens.push([lineNumber, code, pos]);
+ }
+ } else if (code === "&") { // tabalign
+ Tokens.push([lineNumber, code, pos]);
+ } else if (code === "#") { // macro parameter
+ Tokens.push([lineNumber, code, pos]);
+ } else if (code === "^") { // superscript
+ Tokens.push([lineNumber, code, pos]);
+ } else if (code === "_") { // subscript
+ Tokens.push([lineNumber, code, pos]);
+ } else if (code === "~") { // active character (space)
+ Tokens.push([lineNumber, code, pos]);
+ } else {
+ throw "unrecognised character " + code;
+ }
}
- var read1arg = function (k) {
- var open = Tokens[k+1];
- var env = Tokens[k+2];
- var close = Tokens[k+3];
- var envName;
+ return {tokens: Tokens, comments: Comments, linePosition: linePosition, lineNumber: lineNumber, text: text};
+};
- if(open && open[1] === "\\") {
- envName = open[4];
- return k + 1;
- } else if(open && open[1] === "{" && env && env[1] === "\\" && close && close[1] === "}") {
- envName = env[4];
- return k + 3;
- } else {
- return null;
- }
+var read1arg = function (TokeniseResult, k, options) {
+ var Tokens = TokeniseResult.tokens;
+ var text = TokeniseResult.text;
+ if (options && options.allowStar) {
+ var optional = Tokens[k+1];
+ if (optional && optional[1] === "Text") {
+ var optionalstr = text.substring(optional[2], optional[3]);
+ if (optionalstr === "*") { k++;}
+ };
};
- var read1name = function (k) {
- var open = Tokens[k+1];
- var env = Tokens[k+2];
- var close = Tokens[k+3];
+ var open = Tokens[k+1];
+ var env = Tokens[k+2];
+ var close = Tokens[k+3];
+ var envName;
- if(open && open[1] === "{" && env && env[1] === "Text" && close && close[1] === "}") {
- var envName = text.substring(env[2], env[3]);
- return k + 3;
- } else {
- return null;
- }
- };
-
-
-
- var readOptionalParams = function(k) {
- var params = Tokens[k+1];
-
- if(params && params[1] === "Text") {
- var paramNum = text.substring(params[2], params[3]);
- if (paramNum.match(/^\[\d+\]$/)) {
- return k + 1;
- };
- };
- return null;
- };
-
- var readDefinition = function(k) {
- k = k + 1;
- var count = 0;
- var nextToken = Tokens[k];
- while (nextToken && nextToken[1] === "Text") {
- var start = nextToken[2], end = nextToken[3];
- for (i = start; i < end; i++) {
- var char = text[i];
- if (char === ' ' || char === '\t' || char === '\r' || char === '\n') { continue; }
- return null;
- }
- k++;
- nextToken = Tokens[k];
- }
- if (nextToken && nextToken[1] === "{") {
- count++;
- while (count>0) {
- k++;
- nextToken = Tokens[k];
- if(!nextToken) { break; };
- if (nextToken[1] === "}") { count--; }
- if (nextToken[1] === "{") { count++; }
- }
- return k;
- }
- return null;
- };
-
- for (var _j = 0, _len = Tokens.length; _j < _len; _j++) {
- var token = Tokens[_j];
- var line = token[0], type = token[1], start = token[2], end = token[3], seq = token[4];
- if (type === "\\") {
- if (seq === "begin" || seq === "end") {
- var open = Tokens[_j+1];
- var env = Tokens[_j+2];
- var close = Tokens[_j+3];
- if(open && open[1] === "{" && env && env[1] === "Text" && close && close[1] === "}") {
- var envName = text.substring(env[2], env[3]);
- Environments.push({command: seq, name: envName, token: token, closeToken: close});
- _j = _j + 3; // advance past these tokens
- } else {
- var endToken = null;
- if (open && open[1] === "{") {
- endToken = open;
-
- if (env && env[1] === "Text") {
- endToken = env.slice();
- start = endToken[2]; end = endToken[3];
- for (i = start; i < end; i++) {
- char = text[i];
- if (char === ' ' || char === '\t' || char === '\r' || char === '\n') { break; }
- }
- endToken[3] = i;
- };
- };
-
- if (endToken) {
- TokenErrorFromTo(token, endToken, "invalid environment command" + text.substring(token[2], endToken[3] || endToken[2]));
- } else {
- TokenError(token, "invalid environment command");
- };
- }
- } else if (seq === "newcommand" || seq === "renewcommand" || seq === "def" || seq === "DeclareRobustCommand") {
-
- var newPos = read1arg(_j);
- if (newPos === null) { continue; } else {_j = newPos;};
-
- newPos = readOptionalParams(_j);
- if (newPos === null) { /* do nothing */ } else {_j = newPos;};
-
- newPos = readDefinition(_j);
- if (newPos === null) { /* do nothing */ } else {_j = newPos;};
-
- } else if (seq === "newenvironment") {
-
- newPos = read1name(_j);
- if (newPos === null) { continue; } else {_j = newPos;};
-
- newPos = readOptionalParams(_j);
- if (newPos === null) { /* do nothing */ } else {_j = newPos;};
-
- newPos = readDefinition(_j);
- if (newPos === null) { /* do nothing */ } else {_j = newPos;};
-
- newPos = readDefinition(_j);
- if (newPos === null) { /* do nothing */ } else {_j = newPos;};
- }
- } else if (type === "{") {
- Environments.push({command:"{", token:token});
- } else if (type === "}") {
- Environments.push({command:"}", token:token});
- };
-
- if ((start != null) && (end != null) && (seq != null)) {
- } else if ((start != null) && (end != null)) {
- } else if (start != null) {
- } else {
- }
+ if(open && open[1] === "\\") {
+ envName = open[4]; // array element 4 is command sequence
+ return k + 1;
+ } else if(open && open[1] === "{" && env && env[1] === "\\" && close && close[1] === "}") {
+ envName = env[4]; // NOTE: if we were actually using this, keep track of * above
+ return k + 3; // array element 4 is command sequence
+ } else {
+ return null;
}
+};
+
+
+var read1name = function (TokeniseResult, k) {
+ var Tokens = TokeniseResult.tokens;
+ var text = TokeniseResult.text;
+
+ var open = Tokens[k+1];
+ var env = Tokens[k+2];
+ var close = Tokens[k+3];
+
+ if(open && open[1] === "{" && env && env[1] === "Text" && close && close[1] === "}") {
+ var envName = text.substring(env[2], env[3]);
+ return k + 3;
+ } else if (open && open[1] === "{" && env && env[1] === "Text") {
+ envName = "";
+ for (var j = k + 2, tok; (tok = Tokens[j]); j++) {
+ if (tok[1] === "Text") {
+ var str = text.substring(tok[2], tok[3]);
+ if (!str.match(/^\S*$/)) { break; }
+ envName = envName + str;
+ } else if (tok[1] === "_") {
+ envName = envName + "_";
+ } else {
+ break;
+ }
+ }
+ if (tok && tok[1] === "}") {
+ return j; // advance past these tokens
+ } else {
+ return null;
+ }
+ } else {
+ return null;
+ }
+};
+
+var readOptionalParams = function(TokeniseResult, k) {
+ var Tokens = TokeniseResult.tokens;
+ var text = TokeniseResult.text;
+
+ var params = Tokens[k+1];
+
+ if(params && params[1] === "Text") {
+ var paramNum = text.substring(params[2], params[3]);
+ if (paramNum.match(/^\[\d+\](\[[^\]]*\])*\s*$/)) {
+ return k + 1; // got it
+ };
+ };
+ return null;
+};
+
+var readDefinition = function(TokeniseResult, k) {
+ var Tokens = TokeniseResult.tokens;
+ var text = TokeniseResult.text;
+
+ k = k + 1;
+ var count = 0;
+ var nextToken = Tokens[k];
+ while (nextToken && nextToken[1] === "Text") {
+ var start = nextToken[2], end = nextToken[3];
+ for (var i = start; i < end; i++) {
+ var char = text[i];
+ if (char === ' ' || char === '\t' || char === '\r' || char === '\n') { continue; }
+ return null; // bail out, should begin with a {
+ }
+ k++;
+ nextToken = Tokens[k];
+ }
+ if (nextToken && nextToken[1] === "{") {
+ count++;
+ while (count>0) {
+ k++;
+ nextToken = Tokens[k];
+ if(!nextToken) { break; };
+ if (nextToken[1] === "}") { count--; }
+ if (nextToken[1] === "{") { count++; }
+ }
+ return k;
+ }
+
+ return null;
+};
+
+var readVerb = function(TokeniseResult, k) {
+
+ var Tokens = TokeniseResult.tokens;
+ var text = TokeniseResult.text;
+
+ var verbToken = Tokens[k];
+ var verbStr = text.substring(verbToken[2], verbToken[3]);
+ var pos = verbToken[3];
+ if (text[pos] === "*") { pos++; } // \verb* form of command
+ var delimiter = text[pos];
+ pos++;
+
+ var nextToken = Tokens[k+1];
+ for (var i = pos, end = text.length; i < end; i++) {
+ var char = text[i];
+ if (nextToken && i >= nextToken[2]) { k++; nextToken = Tokens[k+1];};
+ if (char === delimiter) { return k; };
+ if (char === '\r' || char === '\n') { return null; }
+ };
+
+ return null;
+};
+
+var readUrl = function(TokeniseResult, k) {
+
+ var Tokens = TokeniseResult.tokens;
+ var text = TokeniseResult.text;
+
+ var urlToken = Tokens[k];
+ var urlStr = text.substring(urlToken[2], urlToken[3]);
+ var pos = urlToken[3];
+ var openDelimiter = text[pos];
+ var closeDelimiter = (openDelimiter === "{") ? "}" : openDelimiter;
+ var nextToken = Tokens[k+1];
+ if (nextToken && pos === nextToken[2]) {
+ k++;
+ nextToken = Tokens[k+1];
+ };
+ pos++;
+
+ var count = 1;
+ for (var i = pos, end = text.length; count > 0 && i < end; i++) {
+ var char = text[i];
+ if (nextToken && i >= nextToken[2]) { k++; nextToken = Tokens[k+1];};
+ if (char === closeDelimiter) {
+ count--;
+ } else if (char === openDelimiter) {
+ count++;
+ };
+ if (count === 0) { return k; };
+ if (char === '\r' || char === '\n') { return null; }
+ };
+
+ return null;
+};
+
+
+var InterpretTokens = function (TokeniseResult, ErrorReporter) {
+ var Tokens = TokeniseResult.tokens;
+ var linePosition = TokeniseResult.linePosition;
+ var lineNumber = TokeniseResult.lineNumber;
+ var text = TokeniseResult.text;
+
+ var TokenErrorFromTo = ErrorReporter.TokenErrorFromTo;
+ var TokenError = ErrorReporter.TokenError;
+ var Environments = [];
+
+ for (var i = 0, len = Tokens.length; i < len; i++) {
+ var token = Tokens[i];
+ var line = token[0], type = token[1], start = token[2], end = token[3], seq = token[4];
+ if (type === "\\") {
+ if (seq === "begin" || seq === "end") {
+ var open = Tokens[i+1];
+ var env = Tokens[i+2];
+ var close = Tokens[i+3];
+ if(open && open[1] === "{" && env && env[1] === "Text" && close && close[1] === "}") {
+ var envName = text.substring(env[2], env[3]);
+ Environments.push({command: seq, name: envName, token: token, closeToken: close});
+ i = i + 3; // advance past these tokens
+ } else {
+ if (open && open[1] === "{" && env && env[1] === "Text") {
+ envName = "";
+ for (var j = i + 2, tok; (tok = Tokens[j]); j++) {
+ if (tok[1] === "Text") {
+ var str = text.substring(tok[2], tok[3]);
+ if (!str.match(/^\S*$/)) { break; }
+ envName = envName + str;
+ } else if (tok[1] === "_") {
+ envName = envName + "_";
+ } else {
+ break;
+ }
+ }
+ if (tok && tok[1] === "}") {
+ Environments.push({command: seq, name: envName, token: token, closeToken: close});
+ i = j; // advance past these tokens
+ continue;
+ }
+ }
+ var endToken = null;
+ if (open && open[1] === "{") {
+ endToken = open; // we've got a {
+ if (env && env[1] === "Text") {
+ endToken = env.slice(); // we've got some text following the {
+ start = endToken[2]; end = endToken[3];
+ for (j = start; j < end; j++) {
+ var char = text[j];
+ if (char === ' ' || char === '\t' || char === '\r' || char === '\n') { break; }
+ }
+ endToken[3] = j; // the end of partial token is as far as we got looking ahead
+ };
+ };
+
+ if (endToken) {
+ TokenErrorFromTo(token, endToken, "invalid environment command " + text.substring(token[2], endToken[3] || endToken[2]));
+ } else {
+ TokenError(token, "invalid environment command");
+ };
+ }
+ } else if (seq === "newcommand" || seq === "renewcommand" || seq === "def" || seq === "DeclareRobustCommand") {
+ var newPos = read1arg(TokeniseResult, i, {allowStar: (seq != "def")});
+ if (newPos === null) { continue; } else {i = newPos;};
+ newPos = readOptionalParams(TokeniseResult, i);
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
+ newPos = readDefinition(TokeniseResult, i);
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
+
+ } else if (seq === "newcolumntype") {
+ newPos = read1name(TokeniseResult, i);
+ if (newPos === null) { continue; } else {i = newPos;};
+ newPos = readOptionalParams(TokeniseResult, i);
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
+ newPos = readDefinition(TokeniseResult, i);
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
+
+ } else if (seq === "newenvironment" || seq === "renewenvironment") {
+ newPos = read1name(TokeniseResult, i);
+ if (newPos === null) { continue; } else {i = newPos;};
+ newPos = readOptionalParams(TokeniseResult, i);
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
+ newPos = readDefinition(TokeniseResult, i);
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
+ newPos = readDefinition(TokeniseResult, i);
+ if (newPos === null) { /* do nothing */ } else {i = newPos;};
+ } else if (seq === "verb") {
+ newPos = readVerb(TokeniseResult, i);
+ if (newPos === null) { TokenError(token, "invalid verbatim command"); } else {i = newPos;};
+ } else if (seq === "url") {
+ newPos = readUrl(TokeniseResult, i);
+ if (newPos === null) { TokenError(token, "invalid url command"); } else {i = newPos;};
+ }
+ } else if (type === "{") {
+ Environments.push({command:"{", token:token});
+ } else if (type === "}") {
+ Environments.push({command:"}", token:token});
+ };
+ };
+ return Environments;
+};
+
+
+var CheckEnvironments = function (Environments, ErrorReporter) {
+ var ErrorTo = ErrorReporter.EnvErrorTo;
+ var ErrorFromTo = ErrorReporter.EnvErrorFromTo;
+ var ErrorFrom = ErrorReporter.EnvErrorFrom;
+
var state = [];
- for (i = 0; i < Environments.length; i++) {
- var thisEnv = Environments[i];
- if(thisEnv.command === "begin" || thisEnv.command === "{") {
- state.push(thisEnv);
- } else if (thisEnv.command === "end" || thisEnv.command === "}") {
- var lastEnv = state.pop();
- if (!lastEnv) {
- if (thisEnv.command === "}") {
- EnvErrorTo(thisEnv, "unexpected end group }");
- } else if (thisEnv.command === "end") {
- EnvErrorTo(thisEnv, "unexpected \\end{" + thisEnv.name + "}");
- }
- } else if (lastEnv.command === "{" && thisEnv.command === "}") {
- continue; // closed group correctly
- } else if (lastEnv.name === thisEnv.name) {
- continue; // closed environment correctly
- } else if (thisEnv.command === "}") {
- EnvErrorFromTo(lastEnv, thisEnv, "unexpected end group } after \\begin{" + lastEnv.name +"}");
- state.push(lastEnv);
- } else if (lastEnv.command === "{" && thisEnv.command === "end") {
- EnvErrorFromTo(lastEnv, thisEnv, "unexpected \\end{" + thisEnv.name + "} inside group {", {suppressIfEditing:true});
- i--;
- } else if (lastEnv.command === "begin" && thisEnv.command === "end") {
- EnvErrorFromTo(lastEnv, thisEnv, "unexpected \\end{" + thisEnv.name + "} after \\begin{" + lastEnv.name + "}");
- for (var j = i + 1; j < Environments.length; j++) {
- var futureEnv = Environments[j];
- if (futureEnv.command === "end" && futureEnv.name === lastEnv.name) {
- state.push(lastEnv);
- continue;
- }
- }
- lastEnv = state.pop();
- if(lastEnv) {
- if (thisEnv.name === lastEnv.name) {
- continue;
- } else {
- state.push(lastEnv);
- }
- }
+ var documentClosed = null;
+ var inVerbatim = false;
+ var verbatimRanges = [];
+ for (var i = 0, len = Environments.length; i < len; i++) {
+ var name = Environments[i].name ;
+ if (name && name.match(/^(verbatim|boxedverbatim|lstlisting)$/)) {
+ Environments[i].verbatim = true;
+ }
+ }
+ for (i = 0, len = Environments.length; i < len; i++) {
+ var thisEnv = Environments[i];
+ if(thisEnv.command === "begin" || thisEnv.command === "{") {
+ if (inVerbatim) { continue; } // ignore anything in verbatim environments
+ if (thisEnv.verbatim) {inVerbatim = true;};
+ state.push(thisEnv);
+ } else if (thisEnv.command === "end" || thisEnv.command === "}") {
+ var lastEnv = state.pop();
- }
- }
+ if (inVerbatim) {
+ if (lastEnv && lastEnv.name === thisEnv.name) {
+ inVerbatim = false;
+ verbatimRanges.push({start: lastEnv.token[2], end: thisEnv.token[2]});
+ continue;
+ } else {
+ if(lastEnv) { state.push(lastEnv); } ;
+ continue; // ignore all other commands
+ }
+ };
+
+ if (lastEnv && lastEnv.command === "{" && thisEnv.command === "}") {
+ continue;
+ } else if (lastEnv && lastEnv.name === thisEnv.name) {
+ if (thisEnv.name === "document" && !documentClosed) {
+ documentClosed = thisEnv;
+ };
+ continue;
+ } else if (!lastEnv) {
+ if (thisEnv.command === "}") {
+ if (documentClosed) {
+ ErrorFromTo(documentClosed, thisEnv, "\\end{" + documentClosed.name + "} is followed by unexpected end group }",{errorAtStart: true, type: "info"});
+ } else {
+ ErrorTo(thisEnv, "unexpected end group }");
+ };
+ } else if (thisEnv.command === "end") {
+ if (documentClosed) {
+ ErrorFromTo(documentClosed, thisEnv, "\\end{" + documentClosed.name + "} is followed by unexpected content",{errorAtStart: true, type: "info"});
+ } else {
+ ErrorTo(thisEnv, "unexpected \\end{" + thisEnv.name + "}");
+ }
+ }
+ } else if (lastEnv.command === "begin" && thisEnv.command === "}") {
+ ErrorFromTo(lastEnv, thisEnv, "unexpected end group } after \\begin{" + lastEnv.name +"}");
+ state.push(lastEnv);
+ } else if (lastEnv.command === "{" && thisEnv.command === "end") {
+ ErrorFromTo(lastEnv, thisEnv,
+ "unclosed group { found at \\end{" + thisEnv.name + "}",
+ {suppressIfEditing:true, errorAtStart: true, type:"warning"});
+ i--;
+ } else if (lastEnv.command === "begin" && thisEnv.command === "end") {
+ ErrorFromTo(lastEnv, thisEnv,
+ "unclosed \\begin{" + lastEnv.name + "} found at \\end{" + thisEnv.name + "} " ,
+ {errorAtStart: true});
+ for (var j = i + 1; j < len; j++) {
+ var futureEnv = Environments[j];
+ if (futureEnv.command === "end" && futureEnv.name === lastEnv.name) {
+ state.push(lastEnv);
+ continue;
+ }
+ }
+ lastEnv = state.pop();
+ if(lastEnv) {
+ if (thisEnv.name === lastEnv.name) {
+ continue;
+ } else {
+ state.push(lastEnv);
+ }
+ }
+
+ }
+ }
}
while (state.length > 0) {
- thisEnv = state.pop();
- if (thisEnv.command === "{") {
- EnvErrorFrom(thisEnv, "unclosed group {");
- } else if (thisEnv.command === "begin") {
- EnvErrorFrom(thisEnv, "unclosed environment \\begin{" + thisEnv.name + "}");
- };
+ thisEnv = state.pop();
+ if (thisEnv.command === "{") {
+ ErrorFrom(thisEnv, "unclosed group {", {type:"warning"});
+ } else if (thisEnv.command === "begin") {
+ ErrorFrom(thisEnv, "unclosed environment \\begin{" + thisEnv.name + "}");
+ };
}
- return errors;
+ var vlen = verbatimRanges.length;
+ len = ErrorReporter.tokenErrors.length;
+ if (vlen >0 && len > 0) {
+ for (i = 0; i < len; i++) {
+ var tokenError = ErrorReporter.tokenErrors[i];
+ var startPos = tokenError.startPos;
+ var endPos = tokenError.endPos;
+ for (j = 0; j < vlen; j++) {
+ if (startPos > verbatimRanges[j].start && startPos < verbatimRanges[j].end) {
+ tokenError.ignore = true;
+ break;
+ }
+ }
+ }
+ }
+
+};
+var ErrorReporter = function (TokeniseResult) {
+ var text = TokeniseResult.text;
+ var linePosition = TokeniseResult.linePosition;
+ var lineNumber = TokeniseResult.lineNumber;
+
+ var errors = [], tokenErrors = [];
+ this.errors = errors;
+ this.tokenErrors = tokenErrors;
+
+ this.getErrors = function () {
+ var returnedErrors = [];
+ for (var i = 0, len = tokenErrors.length; i < len; i++) {
+ if (!tokenErrors[i].ignore) { returnedErrors.push(tokenErrors[i]); }
+ }
+ return returnedErrors.concat(errors);
+ };
+
+ this.TokenError = function (token, message) {
+ var line = token[0], type = token[1], start = token[2], end = token[3];
+ var start_col = start - linePosition[line];
+ var end_col = end - linePosition[line];
+ tokenErrors.push({row: line,
+ column: start_col,
+ start_row:line,
+ start_col: start_col,
+ end_row:line,
+ end_col: end_col,
+ type:"error",
+ text:message,
+ startPos: start,
+ endPos: end,
+ suppressIfEditing:true});
+ };
+
+ this.TokenErrorFromTo = function (fromToken, toToken, message) {
+ var fromLine = fromToken[0], fromStart = fromToken[2], fromEnd = fromToken[3];
+ var toLine = toToken[0], toStart = toToken[2], toEnd = toToken[3];
+ if (!toEnd) { toEnd = toStart + 1;};
+ var start_col = fromStart - linePosition[fromLine];
+ var end_col = toEnd - linePosition[toLine];
+
+ tokenErrors.push({row: fromLine,
+ column: start_col,
+ start_row: fromLine,
+ start_col: start_col,
+ end_row: toLine,
+ end_col: end_col,
+ type:"error",
+ text:message,
+ startPos: fromStart,
+ endPos: toEnd,
+ suppressIfEditing:true});
+ };
+
+
+ this.EnvErrorFromTo = function (fromEnv, toEnv, message, options) {
+ if(!options) { options = {} ; };
+ var fromToken = fromEnv.token, toToken = toEnv.closeToken || toEnv.token;
+ var fromLine = fromToken[0], fromStart = fromToken[2], fromEnd = fromToken[3];
+ if (!toToken) {toToken = fromToken;};
+ var toLine = toToken[0], toStart = toToken[2], toEnd = toToken[3];
+ if (!toEnd) { toEnd = toStart + 1;};
+ var start_col = fromStart - linePosition[fromLine];
+ var end_col = toEnd - linePosition[toLine];
+ errors.push({row: options.errorAtStart ? fromLine : toLine,
+ column: options.errorAtStart ? start_col: end_col,
+ start_row:fromLine,
+ start_col: start_col,
+ end_row:toLine,
+ end_col: end_col,
+ type: options.type ? options.type : "error",
+ text:message,
+ suppressIfEditing:options.suppressIfEditing});
+ };
+
+ this.EnvErrorTo = function (toEnv, message, options) {
+ if(!options) { options = {} ; };
+ var token = toEnv.closeToken || toEnv.token;
+ var line = token[0], type = token[1], start = token[2], end = token[3];
+ if (!end) { end = start + 1; };
+ var end_col = end - linePosition[line];
+ var err = {row: line,
+ column: end_col,
+ start_row:0,
+ start_col: 0,
+ end_row: line,
+ end_col: end_col,
+ type: options.type ? options.type : "error",
+ text:message};
+ errors.push(err);
+ };
+
+ this.EnvErrorFrom = function (env, message, options) {
+ if(!options) { options = {} ; };
+ var token = env.token;
+ var line = token[0], type = token[1], start = token[2], end = token[3];
+ var start_col = start - linePosition[line];
+ var end_col = Infinity;
+ errors.push({row: line,
+ column: start_col,
+ start_row:line,
+ start_col: start_col,
+ end_row: lineNumber,
+ end_col: end_col,
+ type: options.type ? options.type : "error",
+ text:message});
+ };
+};
+
+var Parse = function (text) {
+ var TokeniseResult = Tokenise(text);
+ var Reporter = new ErrorReporter(TokeniseResult);
+ var Environments = InterpretTokens(TokeniseResult, Reporter);
+ CheckEnvironments(Environments, Reporter);
+ return Reporter.getErrors();
};
(function() {
var disabled = false;
this.onUpdate = function() {
- if (disabled) { return ; };
+ if (disabled) { return ; };
- var value = this.doc.getValue();
- var errors = [];
- try {
- if (value)
- errors = Parse(value);
- } catch (e) {
- disabled = true;
- errors = [];
- }
- this.sender.emit("lint", errors);
+ var value = this.doc.getValue();
+ var errors = [];
+ try {
+ if (value)
+ errors = Parse(value);
+ } catch (e) {
+ disabled = true;
+ errors = [];
+ }
+ this.sender.emit("lint", errors);
};
}).call(LatexWorker.prototype);
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/.gitattributes b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/.gitattributes
new file mode 100644
index 0000000000..556f8c827b
--- /dev/null
+++ b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/.gitattributes
@@ -0,0 +1 @@
+* binary
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-EUC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-EUC-H.bcmap
new file mode 100644
index 0000000000..2655fc70ae
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-EUC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-EUC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-EUC-V.bcmap
new file mode 100644
index 0000000000..f1ed853828
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-EUC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-H.bcmap
new file mode 100644
index 0000000000..39e89d3339
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-RKSJ-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-RKSJ-H.bcmap
new file mode 100644
index 0000000000..e4167cb51f
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-RKSJ-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-RKSJ-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-RKSJ-V.bcmap
new file mode 100644
index 0000000000..50b1646e94
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-RKSJ-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-V.bcmap
new file mode 100644
index 0000000000..d7af99b5e2
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78ms-RKSJ-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78ms-RKSJ-H.bcmap
new file mode 100644
index 0000000000..37077d01e2
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78ms-RKSJ-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78ms-RKSJ-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78ms-RKSJ-V.bcmap
new file mode 100644
index 0000000000..acf23231ae
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/78ms-RKSJ-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/83pv-RKSJ-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/83pv-RKSJ-H.bcmap
new file mode 100644
index 0000000000..2359bc529d
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/83pv-RKSJ-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90ms-RKSJ-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90ms-RKSJ-H.bcmap
new file mode 100644
index 0000000000..af8293829c
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90ms-RKSJ-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90ms-RKSJ-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90ms-RKSJ-V.bcmap
new file mode 100644
index 0000000000..780549de19
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90ms-RKSJ-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90msp-RKSJ-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90msp-RKSJ-H.bcmap
new file mode 100644
index 0000000000..bfd3119c62
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90msp-RKSJ-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90msp-RKSJ-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90msp-RKSJ-V.bcmap
new file mode 100644
index 0000000000..25ef14ab4a
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90msp-RKSJ-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90pv-RKSJ-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90pv-RKSJ-H.bcmap
new file mode 100644
index 0000000000..02f713bb83
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90pv-RKSJ-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90pv-RKSJ-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90pv-RKSJ-V.bcmap
new file mode 100644
index 0000000000..d08e0cc5d9
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/90pv-RKSJ-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-H.bcmap
new file mode 100644
index 0000000000..59442acafb
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-RKSJ-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-RKSJ-H.bcmap
new file mode 100644
index 0000000000..a3065e441a
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-RKSJ-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-RKSJ-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-RKSJ-V.bcmap
new file mode 100644
index 0000000000..040014cfc0
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-RKSJ-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-V.bcmap
new file mode 100644
index 0000000000..2f816d320f
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Add-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-0.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-0.bcmap
new file mode 100644
index 0000000000..88ec04af49
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-0.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-1.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-1.bcmap
new file mode 100644
index 0000000000..03a501477c
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-1.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-2.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-2.bcmap
new file mode 100644
index 0000000000..2aa95141f9
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-2.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-3.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-3.bcmap
new file mode 100644
index 0000000000..86d8b8c79c
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-3.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-4.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-4.bcmap
new file mode 100644
index 0000000000..f50fc6c14e
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-4.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-5.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-5.bcmap
new file mode 100644
index 0000000000..6caf4a8314
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-5.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-6.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-6.bcmap
new file mode 100644
index 0000000000..b77fb0705c
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-6.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-UCS2.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-UCS2.bcmap
new file mode 100644
index 0000000000..69d79a2c2c
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-CNS1-UCS2.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-0.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-0.bcmap
new file mode 100644
index 0000000000..36101083fa
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-0.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-1.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-1.bcmap
new file mode 100644
index 0000000000..707bb1065c
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-1.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-2.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-2.bcmap
new file mode 100644
index 0000000000..f7648cc3ff
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-2.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-3.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-3.bcmap
new file mode 100644
index 0000000000..852145890e
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-3.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-4.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-4.bcmap
new file mode 100644
index 0000000000..e40c63ab1e
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-4.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-5.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-5.bcmap
new file mode 100644
index 0000000000..d7623b5002
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-5.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-UCS2.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-UCS2.bcmap
new file mode 100644
index 0000000000..7586525936
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-GB1-UCS2.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-0.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-0.bcmap
new file mode 100644
index 0000000000..f0e94ec196
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-0.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-1.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-1.bcmap
new file mode 100644
index 0000000000..dad42c5ad7
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-1.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-2.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-2.bcmap
new file mode 100644
index 0000000000..090819a064
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-2.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-3.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-3.bcmap
new file mode 100644
index 0000000000..087dfc1558
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-3.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-4.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-4.bcmap
new file mode 100644
index 0000000000..46aa9bffe5
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-4.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-5.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-5.bcmap
new file mode 100644
index 0000000000..5b4b65cc62
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-5.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-6.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-6.bcmap
new file mode 100644
index 0000000000..e77d699ab6
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-6.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-UCS2.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-UCS2.bcmap
new file mode 100644
index 0000000000..128a141077
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Japan1-UCS2.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-0.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-0.bcmap
new file mode 100644
index 0000000000..cef1a99851
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-0.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-1.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-1.bcmap
new file mode 100644
index 0000000000..11ffa36df8
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-1.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-2.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-2.bcmap
new file mode 100644
index 0000000000..3172308c79
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-2.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-UCS2.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-UCS2.bcmap
new file mode 100644
index 0000000000..f3371c0cbd
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Adobe-Korea1-UCS2.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5-H.bcmap
new file mode 100644
index 0000000000..beb4d22810
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5-V.bcmap
new file mode 100644
index 0000000000..2d4f87d503
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5pc-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5pc-H.bcmap
new file mode 100644
index 0000000000..ce0013167f
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5pc-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5pc-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5pc-V.bcmap
new file mode 100644
index 0000000000..73b99ff2fb
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/B5pc-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS-EUC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS-EUC-H.bcmap
new file mode 100644
index 0000000000..61d1d0cb00
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS-EUC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS-EUC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS-EUC-V.bcmap
new file mode 100644
index 0000000000..1a393a51e0
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS-EUC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS1-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS1-H.bcmap
new file mode 100644
index 0000000000..f738e218ae
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS1-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS1-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS1-V.bcmap
new file mode 100644
index 0000000000..9c3169f0d9
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS1-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS2-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS2-H.bcmap
new file mode 100644
index 0000000000..c89b3527fe
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS2-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS2-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS2-V.bcmap
new file mode 100644
index 0000000000..7588cec83e
--- /dev/null
+++ b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/CNS2-V.bcmap
@@ -0,0 +1,3 @@
+àRCopyright 1990-2009 Adobe Systems Incorporated.
+All rights reserved.
+See ./LICENSEáCNS2-H
\ No newline at end of file
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETHK-B5-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETHK-B5-H.bcmap
new file mode 100644
index 0000000000..cb29415de4
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETHK-B5-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETHK-B5-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETHK-B5-V.bcmap
new file mode 100644
index 0000000000..f09aec6318
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETHK-B5-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETen-B5-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETen-B5-H.bcmap
new file mode 100644
index 0000000000..c2d77462d2
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETen-B5-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETen-B5-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETen-B5-V.bcmap
new file mode 100644
index 0000000000..89bff159ec
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETen-B5-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETenms-B5-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETenms-B5-H.bcmap
new file mode 100644
index 0000000000..a7d69db5e3
--- /dev/null
+++ b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETenms-B5-H.bcmap
@@ -0,0 +1,3 @@
+àRCopyright 1990-2009 Adobe Systems Incorporated.
+All rights reserved.
+See ./LICENSEá ETen-B5-H` ^
\ No newline at end of file
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETenms-B5-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETenms-B5-V.bcmap
new file mode 100644
index 0000000000..adc5d618d6
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/ETenms-B5-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/EUC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/EUC-H.bcmap
new file mode 100644
index 0000000000..e92ea5b3b9
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/EUC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/EUC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/EUC-V.bcmap
new file mode 100644
index 0000000000..7a7c183228
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/EUC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-H.bcmap
new file mode 100644
index 0000000000..3b5cde44db
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-RKSJ-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-RKSJ-H.bcmap
new file mode 100644
index 0000000000..ea4d2d97b8
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-RKSJ-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-RKSJ-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-RKSJ-V.bcmap
new file mode 100644
index 0000000000..3457c27709
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-RKSJ-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-V.bcmap
new file mode 100644
index 0000000000..4999ca4041
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Ext-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-EUC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-EUC-H.bcmap
new file mode 100644
index 0000000000..e39908b984
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-EUC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-EUC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-EUC-V.bcmap
new file mode 100644
index 0000000000..d5be5446aa
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-EUC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-H.bcmap
new file mode 100644
index 0000000000..39189c54e3
--- /dev/null
+++ b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-H.bcmap
@@ -0,0 +1,4 @@
+àRCopyright 1990-2009 Adobe Systems Incorporated.
+All rights reserved.
+See ./LICENSE!!�º]aX!!]`�21�> �p�z�$]‚�"R‚d�-Uƒ7�*„
4„%�+ „Z „{�/…%…<�9K…b�1]†.�"‡‰`]‡,�"]ˆ
+�"]ˆh�"]‰F�"]Š$�"]‹�"]‹`�"]Œ>�"]��"]�z�"]ŽX�"]�6�"]��"]�r�"]‘P�"]’.�"]“�"]“j�"]”H�"]•&�"]–�"]–b�"]—@�"]˜�"]˜|�"]™Z�"]š8�"]›�"]›t�"]œR�"]�0�"]ž�"]žl�"]ŸJ�"] (�"]¡�"]¡d�"]¢B�"]£ �"X£~�']¤W�"]¥5�"]¦�"]¦q�"]§O�"]¨-�"]©�"]©i�"]ªG�"]«%�"]¬�"]¬a�"]?�"]®�"]®{�"]¯Y�"]°7�"]±�"]±s�"]²Q�"]³/�"]´
�"]´k�"]µI�"]¶'�"]·�"]·c�"]¸A�"]¹�"]¹}�"]º[�"]»9
\ No newline at end of file
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-V.bcmap
new file mode 100644
index 0000000000..310834512f
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GB-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK-EUC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK-EUC-H.bcmap
new file mode 100644
index 0000000000..05fff7e825
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK-EUC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK-EUC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK-EUC-V.bcmap
new file mode 100644
index 0000000000..0cdf6bed6d
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK-EUC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK2K-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK2K-H.bcmap
new file mode 100644
index 0000000000..46f6ba5967
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK2K-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK2K-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK2K-V.bcmap
new file mode 100644
index 0000000000..d9a9479843
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBK2K-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBKp-EUC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBKp-EUC-H.bcmap
new file mode 100644
index 0000000000..5cb0af687e
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBKp-EUC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBKp-EUC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBKp-EUC-V.bcmap
new file mode 100644
index 0000000000..bca93b8efb
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBKp-EUC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-EUC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-EUC-H.bcmap
new file mode 100644
index 0000000000..4b4e2d3229
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-EUC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-EUC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-EUC-V.bcmap
new file mode 100644
index 0000000000..38f706699f
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-EUC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-H.bcmap
new file mode 100644
index 0000000000..8437ac3377
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-V.bcmap
new file mode 100644
index 0000000000..697ab4a8e7
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBT-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBTpc-EUC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBTpc-EUC-H.bcmap
new file mode 100644
index 0000000000..f6e50e8936
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBTpc-EUC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBTpc-EUC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBTpc-EUC-V.bcmap
new file mode 100644
index 0000000000..6c0d71a2d0
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBTpc-EUC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBpc-EUC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBpc-EUC-H.bcmap
new file mode 100644
index 0000000000..c9edf67cf6
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBpc-EUC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBpc-EUC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBpc-EUC-V.bcmap
new file mode 100644
index 0000000000..31450c97f6
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/GBpc-EUC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/H.bcmap
new file mode 100644
index 0000000000..7b24ea4629
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdla-B5-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdla-B5-H.bcmap
new file mode 100644
index 0000000000..7d30c05005
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdla-B5-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdla-B5-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdla-B5-V.bcmap
new file mode 100644
index 0000000000..78946940d6
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdla-B5-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdlb-B5-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdlb-B5-H.bcmap
new file mode 100644
index 0000000000..d829a23101
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdlb-B5-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdlb-B5-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdlb-B5-V.bcmap
new file mode 100644
index 0000000000..2b572b50a4
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKdlb-B5-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKgccs-B5-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKgccs-B5-H.bcmap
new file mode 100644
index 0000000000..971a4f23f7
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKgccs-B5-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKgccs-B5-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKgccs-B5-V.bcmap
new file mode 100644
index 0000000000..d353ca256b
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKgccs-B5-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm314-B5-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm314-B5-H.bcmap
new file mode 100644
index 0000000000..576dc01112
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm314-B5-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm314-B5-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm314-B5-V.bcmap
new file mode 100644
index 0000000000..0e96d0e228
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm314-B5-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm471-B5-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm471-B5-H.bcmap
new file mode 100644
index 0000000000..11d170c75e
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm471-B5-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm471-B5-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm471-B5-V.bcmap
new file mode 100644
index 0000000000..54959bf9e7
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKm471-B5-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKscs-B5-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKscs-B5-H.bcmap
new file mode 100644
index 0000000000..6ef7857ad1
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKscs-B5-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKscs-B5-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKscs-B5-V.bcmap
new file mode 100644
index 0000000000..1fb2fa2a2e
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/HKscs-B5-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Hankaku.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Hankaku.bcmap
new file mode 100644
index 0000000000..4b8ec7fcef
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Hankaku.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Hiragana.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Hiragana.bcmap
new file mode 100644
index 0000000000..17e983e772
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Hiragana.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-EUC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-EUC-H.bcmap
new file mode 100644
index 0000000000..a45c65f008
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-EUC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-EUC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-EUC-V.bcmap
new file mode 100644
index 0000000000..0e7b21f0a6
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-EUC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-H.bcmap
new file mode 100644
index 0000000000..b9b22b6787
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-Johab-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-Johab-H.bcmap
new file mode 100644
index 0000000000..2531ffcf41
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-Johab-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-Johab-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-Johab-V.bcmap
new file mode 100644
index 0000000000..367ceb226a
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-Johab-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-V.bcmap
new file mode 100644
index 0000000000..6ae2f0b6b7
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-H.bcmap
new file mode 100644
index 0000000000..a8d4240e6a
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-HW-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-HW-H.bcmap
new file mode 100644
index 0000000000..8b4ae18fd3
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-HW-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-HW-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-HW-V.bcmap
new file mode 100644
index 0000000000..b655dbcfb1
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-HW-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-V.bcmap
new file mode 100644
index 0000000000..21f97f65b4
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCms-UHC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCpc-EUC-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCpc-EUC-H.bcmap
new file mode 100644
index 0000000000..e06f361eb6
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCpc-EUC-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCpc-EUC-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCpc-EUC-V.bcmap
new file mode 100644
index 0000000000..f3c9113fcf
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/KSCpc-EUC-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Katakana.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Katakana.bcmap
new file mode 100644
index 0000000000..524303c4f0
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Katakana.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/LICENSE b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/LICENSE
new file mode 100644
index 0000000000..b1ad168ad0
--- /dev/null
+++ b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/LICENSE
@@ -0,0 +1,36 @@
+%%Copyright: -----------------------------------------------------------
+%%Copyright: Copyright 1990-2009 Adobe Systems Incorporated.
+%%Copyright: All rights reserved.
+%%Copyright:
+%%Copyright: Redistribution and use in source and binary forms, with or
+%%Copyright: without modification, are permitted provided that the
+%%Copyright: following conditions are met:
+%%Copyright:
+%%Copyright: Redistributions of source code must retain the above
+%%Copyright: copyright notice, this list of conditions and the following
+%%Copyright: disclaimer.
+%%Copyright:
+%%Copyright: Redistributions in binary form must reproduce the above
+%%Copyright: copyright notice, this list of conditions and the following
+%%Copyright: disclaimer in the documentation and/or other materials
+%%Copyright: provided with the distribution.
+%%Copyright:
+%%Copyright: Neither the name of Adobe Systems Incorporated nor the names
+%%Copyright: of its contributors may be used to endorse or promote
+%%Copyright: products derived from this software without specific prior
+%%Copyright: written permission.
+%%Copyright:
+%%Copyright: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+%%Copyright: CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+%%Copyright: INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+%%Copyright: MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+%%Copyright: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+%%Copyright: CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+%%Copyright: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+%%Copyright: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+%%Copyright: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+%%Copyright: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+%%Copyright: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+%%Copyright: OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+%%Copyright: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+%%Copyright: -----------------------------------------------------------
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/NWP-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/NWP-H.bcmap
new file mode 100644
index 0000000000..afc5e4b05e
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/NWP-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/NWP-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/NWP-V.bcmap
new file mode 100644
index 0000000000..bb5785e327
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/NWP-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/RKSJ-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/RKSJ-H.bcmap
new file mode 100644
index 0000000000..fb8d298e9b
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/RKSJ-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/RKSJ-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/RKSJ-V.bcmap
new file mode 100644
index 0000000000..a2555a6c04
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/RKSJ-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Roman.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Roman.bcmap
new file mode 100644
index 0000000000..f896dcf1c7
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/Roman.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UCS2-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UCS2-H.bcmap
new file mode 100644
index 0000000000..d5db27c5cf
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UCS2-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UCS2-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UCS2-V.bcmap
new file mode 100644
index 0000000000..1dc9b7a21b
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UCS2-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF16-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF16-H.bcmap
new file mode 100644
index 0000000000..961afefb66
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF16-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF16-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF16-V.bcmap
new file mode 100644
index 0000000000..df0cffe86b
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF16-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF32-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF32-H.bcmap
new file mode 100644
index 0000000000..1ab18a1436
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF32-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF32-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF32-V.bcmap
new file mode 100644
index 0000000000..ad14662e25
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF32-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF8-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF8-H.bcmap
new file mode 100644
index 0000000000..83c6bd7c4f
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF8-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF8-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF8-V.bcmap
new file mode 100644
index 0000000000..22a27e4ddb
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniCNS-UTF8-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UCS2-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UCS2-H.bcmap
new file mode 100644
index 0000000000..5bd6228ce6
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UCS2-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UCS2-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UCS2-V.bcmap
new file mode 100644
index 0000000000..53c534b7fe
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UCS2-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF16-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF16-H.bcmap
new file mode 100644
index 0000000000..b95045b400
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF16-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF16-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF16-V.bcmap
new file mode 100644
index 0000000000..51f023e0d6
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF16-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF32-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF32-H.bcmap
new file mode 100644
index 0000000000..f0dbd14f37
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF32-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF32-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF32-V.bcmap
new file mode 100644
index 0000000000..ce9c30a985
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF32-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF8-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF8-H.bcmap
new file mode 100644
index 0000000000..982ca462b1
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF8-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF8-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF8-V.bcmap
new file mode 100644
index 0000000000..f78020dd40
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniGB-UTF8-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-H.bcmap
new file mode 100644
index 0000000000..7daf56afab
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-HW-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-HW-H.bcmap
new file mode 100644
index 0000000000..ac9975c585
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-HW-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-HW-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-HW-V.bcmap
new file mode 100644
index 0000000000..3da0a1c62f
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-HW-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-V.bcmap
new file mode 100644
index 0000000000..c50b9ddfde
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UCS2-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF16-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF16-H.bcmap
new file mode 100644
index 0000000000..6761344639
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF16-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF16-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF16-V.bcmap
new file mode 100644
index 0000000000..70bf90c0ef
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF16-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF32-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF32-H.bcmap
new file mode 100644
index 0000000000..7a83d53ae7
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF32-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF32-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF32-V.bcmap
new file mode 100644
index 0000000000..7a87135394
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF32-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF8-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF8-H.bcmap
new file mode 100644
index 0000000000..9f0334cac7
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF8-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF8-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF8-V.bcmap
new file mode 100644
index 0000000000..808a94f0fd
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS-UTF8-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF16-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF16-H.bcmap
new file mode 100644
index 0000000000..d768bf811f
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF16-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF16-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF16-V.bcmap
new file mode 100644
index 0000000000..3d5bf6fb4e
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF16-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF32-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF32-H.bcmap
new file mode 100644
index 0000000000..09eee10d4f
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF32-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF32-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF32-V.bcmap
new file mode 100644
index 0000000000..6c54600133
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF32-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF8-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF8-H.bcmap
new file mode 100644
index 0000000000..1b1a64f50d
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF8-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF8-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF8-V.bcmap
new file mode 100644
index 0000000000..994aa9ef9f
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJIS2004-UTF8-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISPro-UCS2-HW-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISPro-UCS2-HW-V.bcmap
new file mode 100644
index 0000000000..643f921b65
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISPro-UCS2-HW-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISPro-UCS2-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISPro-UCS2-V.bcmap
new file mode 100644
index 0000000000..c148f67f5e
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISPro-UCS2-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISPro-UTF8-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISPro-UTF8-V.bcmap
new file mode 100644
index 0000000000..1849d809a6
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISPro-UTF8-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX0213-UTF32-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX0213-UTF32-H.bcmap
new file mode 100644
index 0000000000..a83a677c56
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX0213-UTF32-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX0213-UTF32-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX0213-UTF32-V.bcmap
new file mode 100644
index 0000000000..f527248ad5
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX0213-UTF32-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX02132004-UTF32-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX02132004-UTF32-H.bcmap
new file mode 100644
index 0000000000..e1a988dc9e
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX02132004-UTF32-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX02132004-UTF32-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX02132004-UTF32-V.bcmap
new file mode 100644
index 0000000000..47e054a961
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniJISX02132004-UTF32-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UCS2-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UCS2-H.bcmap
new file mode 100644
index 0000000000..b5b94852a5
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UCS2-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UCS2-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UCS2-V.bcmap
new file mode 100644
index 0000000000..026adcaad4
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UCS2-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF16-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF16-H.bcmap
new file mode 100644
index 0000000000..fd4e66e81f
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF16-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF16-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF16-V.bcmap
new file mode 100644
index 0000000000..075efb7054
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF16-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF32-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF32-H.bcmap
new file mode 100644
index 0000000000..769d2142c0
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF32-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF32-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF32-V.bcmap
new file mode 100644
index 0000000000..bdab208b69
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF32-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF8-H.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF8-H.bcmap
new file mode 100644
index 0000000000..6ff8674af7
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF8-H.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF8-V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF8-V.bcmap
new file mode 100644
index 0000000000..8dfa76a58e
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/UniKS-UTF8-V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/V.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/V.bcmap
new file mode 100644
index 0000000000..fdec990662
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/V.bcmap differ
diff --git a/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/WP-Symbol.bcmap b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/WP-Symbol.bcmap
new file mode 100644
index 0000000000..46729bbf30
Binary files /dev/null and b/services/web/public/js/libs/pdfjs-1.6.210p1/bcmaps/WP-Symbol.bcmap differ
diff --git a/services/web/public/stylesheets/app/account-settings.less b/services/web/public/stylesheets/app/account-settings.less
index 23769e055b..c232e36fab 100644
--- a/services/web/public/stylesheets/app/account-settings.less
+++ b/services/web/public/stylesheets/app/account-settings.less
@@ -2,4 +2,11 @@
.alert {
margin-bottom: 0;
}
-}
\ No newline at end of file
+}
+
+#delete-account-modal {
+ .alert {
+ margin-top: 25px;
+ margin-bottom: 4px;
+ }
+}
diff --git a/services/web/public/stylesheets/app/editor.less b/services/web/public/stylesheets/app/editor.less
index 8eb670e5a6..f082ae332e 100644
--- a/services/web/public/stylesheets/app/editor.less
+++ b/services/web/public/stylesheets/app/editor.less
@@ -408,11 +408,13 @@
}
}
+.teaser-title,
.dropbox-teaser-title {
margin-top: 0;
text-align: center;
}
+.teaser-img,
.dropbox-teaser-img {
.img-responsive;
margin-bottom: 5px;
diff --git a/services/web/public/stylesheets/app/editor/history.less b/services/web/public/stylesheets/app/editor/history.less
index cb88be62c1..81af8f989f 100644
--- a/services/web/public/stylesheets/app/editor/history.less
+++ b/services/web/public/stylesheets/app/editor/history.less
@@ -25,6 +25,19 @@
background-color: white;
border-radius: 8px;
}
+ .message-wider {
+ width: 650px;
+ margin-top: 60px;
+ padding: 0;
+ }
+
+ .message-header {
+ .modal-header;
+ }
+
+ .message-body {
+ .modal-body;
+ }
}
.diff-panel {
diff --git a/services/web/public/stylesheets/app/project-list.less b/services/web/public/stylesheets/app/project-list.less
index 8e5da6cb3d..de3307a017 100644
--- a/services/web/public/stylesheets/app/project-list.less
+++ b/services/web/public/stylesheets/app/project-list.less
@@ -200,6 +200,10 @@ ul.structured-list {
.select-item + span, .select-all + span {
display: inline-block;
padding-left: @line-height-computed * 1.5;
+ max-width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ vertical-align: top;
}
}
}
diff --git a/services/web/test/UnitTests/coffee/Email/EmailBuilderTests.coffee b/services/web/test/UnitTests/coffee/Email/EmailBuilderTests.coffee
index ff51507636..4ee0e0ed05 100644
--- a/services/web/test/UnitTests/coffee/Email/EmailBuilderTests.coffee
+++ b/services/web/test/UnitTests/coffee/Email/EmailBuilderTests.coffee
@@ -18,30 +18,6 @@ describe "EmailBuilder", ->
"settings-sharelatex":@settings
"logger-sharelatex": log:->
- describe "projectSharedWithYou", ->
- beforeEach ->
- @opts =
- to:"bob@bob.com"
- first_name:"bob"
- owner:
- email:"sally@hally.com"
- project:
- url:"http://www.project.com"
- name:"standard project"
- @email = @EmailBuilder.buildEmail("projectSharedWithYou", @opts)
-
- it "should insert the owner email into the template", ->
- @email.html.indexOf(@opts.owner.email).should.not.equal -1
- @email.subject.indexOf(@opts.owner.email).should.not.equal -1
-
- it 'should not have text component', ->
- expect(@email.html?).to.equal true
- expect(@email.text?).to.equal false
-
- it "should not have undefined in it", ->
- @email.html.indexOf("undefined").should.equal -1
- @email.subject.indexOf("undefined").should.equal -1
-
describe "projectInvite", ->
beforeEach ->
@opts =
diff --git a/services/web/test/UnitTests/coffee/Project/ProjectLocatorTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectLocatorTests.coffee
index cc56e9f583..1d982d90af 100644
--- a/services/web/test/UnitTests/coffee/Project/ProjectLocatorTests.coffee
+++ b/services/web/test/UnitTests/coffee/Project/ProjectLocatorTests.coffee
@@ -70,6 +70,7 @@ describe 'ProjectLocator', ->
it 'should give error if element could not be found', (done)->
@locator.findElement {project_id:project._id, element_id:"ddsd432nj42", type:"docs"}, (err, foundElement, path, parentFolder)->
+ console.log err
err.should.deep.equal new Errors.NotFoundError("entity not found")
done()
diff --git a/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee b/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee
index 1f935e420f..3a43c8988e 100644
--- a/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee
+++ b/services/web/test/UnitTests/coffee/Subscription/SubscriptionControllerTests.coffee
@@ -20,7 +20,7 @@ mockSubscriptions =
describe "SubscriptionController sanboxed", ->
beforeEach ->
- @user = {email:"tom@yahoo.com", _id: 'one'}
+ @user = {email:"tom@yahoo.com", _id: 'one', signUpDate: new Date('2000-10-01')}
@activeRecurlySubscription = mockSubscriptions["subscription-123-active"]
@AuthenticationController =
@@ -63,6 +63,8 @@ describe "SubscriptionController sanboxed", ->
getCurrencyCode:sinon.stub()
@SubscriptionDomainHandler =
getDomainLicencePage:sinon.stub()
+ @UserGetter =
+ getUser: sinon.stub().callsArgWith(2, null, @user)
@SubscriptionController = SandboxedModule.require modulePath, requires:
'../Authentication/AuthenticationController': @AuthenticationController
'./SubscriptionHandler': @SubscriptionHandler
@@ -76,6 +78,7 @@ describe "SubscriptionController sanboxed", ->
warn:->
"settings-sharelatex": @settings
"./SubscriptionDomainHandler":@SubscriptionDomainHandler
+ "../User/UserGetter": @UserGetter
@res = new MockResponse()
@@ -92,12 +95,31 @@ describe "SubscriptionController sanboxed", ->
@GeoIpLookup.getCurrencyCode.callsArgWith(1, null, @stubbedCurrencyCode)
@res.callback = done
@SubscriptionController.plansPage(@req, @res)
+ @UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user)
it "should set the recommended currency from the geoiplookup", (done)->
@res.renderedVariables.recomendedCurrency.should.equal(@stubbedCurrencyCode)
@GeoIpLookup.getCurrencyCode.calledWith(@req.ip).should.equal true
done()
+ it 'should fetch the current user', (done) ->
+ @UserGetter.getUser.callCount.should.equal 1
+ done()
+
+ it 'should decide not to AB test the plans', (done) ->
+ @res.renderedVariables.shouldABTestPlans.should.equal false
+ done()
+
+ describe 'when user is not logged in', (done) ->
+
+ beforeEach ->
+ @AuthenticationController.getLoggedInUserId.returns(null)
+
+ it 'should not fetch the current user', (done) ->
+ @UserGetter.getUser.callCount.should.equal 0
+ done()
+
+
describe "editBillingDetailsPage", ->
describe "with a user with a subscription", ->
beforeEach (done) ->
diff --git a/services/web/test/UnitTests/coffee/User/UserControllerTests.coffee b/services/web/test/UnitTests/coffee/User/UserControllerTests.coffee
index a9c98e02ec..cc1d2190ef 100644
--- a/services/web/test/UnitTests/coffee/User/UserControllerTests.coffee
+++ b/services/web/test/UnitTests/coffee/User/UserControllerTests.coffee
@@ -84,15 +84,81 @@ describe "UserController", ->
sendStatus: sinon.stub()
json: sinon.stub()
@next = sinon.stub()
- describe "deleteUser", ->
- it "should delete the user", (done)->
+ describe 'tryDeleteUser', ->
- @res.sendStatus = (code)=>
- @UserDeleter.deleteUser.calledWith(@user_id)
+ beforeEach ->
+ @req.body.password = 'wat'
+ @AuthenticationController.getLoggedInUserId = sinon.stub().returns(@user._id)
+ @AuthenticationManager.authenticate = sinon.stub().callsArgWith(2, null, @user)
+ @UserDeleter.deleteUser = sinon.stub().callsArgWith(1, null)
+
+ it 'should send 200', (done) ->
+ @res.sendStatus = (code) =>
code.should.equal 200
done()
- @UserController.deleteUser @req, @res
+ @UserController.tryDeleteUser @req, @res, @next
+
+ it 'should try to authenticate user', (done) ->
+ @res.sendStatus = (code) =>
+ @AuthenticationManager.authenticate.callCount.should.equal 1
+ @AuthenticationManager.authenticate.calledWith({_id: @user._id}, @req.body.password).should.equal true
+ done()
+ @UserController.tryDeleteUser @req, @res, @next
+
+ it 'should delete the user', (done) ->
+ @res.sendStatus = (code) =>
+ @UserDeleter.deleteUser.callCount.should.equal 1
+ @UserDeleter.deleteUser.calledWith(@user._id).should.equal true
+ done()
+ @UserController.tryDeleteUser @req, @res, @next
+
+ describe 'when no password is supplied', ->
+
+ beforeEach ->
+ @req.body.password = ''
+
+ it 'should return 403', (done) ->
+ @res.sendStatus = (code) =>
+ code.should.equal 403
+ done()
+ @UserController.tryDeleteUser @req, @res, @next
+
+ describe 'when authenticate produces an error', ->
+
+ beforeEach ->
+ @AuthenticationManager.authenticate = sinon.stub().callsArgWith(2, new Error('woops'))
+
+ it 'should call next with an error', (done) ->
+ @next = (err) =>
+ expect(err).to.not.equal null
+ expect(err).to.be.instanceof Error
+ done()
+ @UserController.tryDeleteUser @req, @res, @next
+
+ describe 'when authenticate does not produce a user', ->
+
+ beforeEach ->
+ @AuthenticationManager.authenticate = sinon.stub().callsArgWith(2, null, null)
+
+ it 'should return 403', (done) ->
+ @res.sendStatus = (code) =>
+ code.should.equal 403
+ done()
+ @UserController.tryDeleteUser @req, @res, @next
+
+ describe 'when deleteUser produces an error', ->
+
+ beforeEach ->
+ @UserDeleter.deleteUser = sinon.stub().callsArgWith(1, new Error('woops'))
+
+ it 'should call next with an error', (done) ->
+ @next = (err) =>
+ expect(err).to.not.equal null
+ expect(err).to.be.instanceof Error
+ done()
+ @UserController.tryDeleteUser @req, @res, @next
+
describe "unsubscribe", ->
diff --git a/services/web/test/UnitTests/coffee/User/UserRegistrationHandlerTests.coffee b/services/web/test/UnitTests/coffee/User/UserRegistrationHandlerTests.coffee
index d0b96da2de..c59b481dc5 100644
--- a/services/web/test/UnitTests/coffee/User/UserRegistrationHandlerTests.coffee
+++ b/services/web/test/UnitTests/coffee/User/UserRegistrationHandlerTests.coffee
@@ -96,6 +96,7 @@ describe "UserRegistrationHandler", ->
it "should return email registered in the error if there is a non holdingAccount there", (done)->
@User.findOne.callsArgWith(1, null, @user = {holdingAccount:false})
@handler.registerNewUser @passingRequest, (err, user)=>
+ console.log err, user
err.should.deep.equal new Error("EmailAlreadyRegistered")
user.should.deep.equal @user
done()
diff --git a/services/web/test/smoke/coffee/SmokeTests.coffee b/services/web/test/smoke/coffee/SmokeTests.coffee
index 714c32289c..be066bc7dc 100644
--- a/services/web/test/smoke/coffee/SmokeTests.coffee
+++ b/services/web/test/smoke/coffee/SmokeTests.coffee
@@ -25,8 +25,14 @@ convertCookieFile = (callback) ->
describe "Opening", ->
before (done) ->
- require("../../../app/js/Features/Security/LoginRateLimiter.js").recordSuccessfulLogin Settings.smokeTest.user, ->
+ logger.log "smoke test: setup"
+ require("../../../app/js/Features/Security/LoginRateLimiter.js").recordSuccessfulLogin Settings.smokeTest.user, (err)->
+ if err?
+ logger.err err:err, "smoke test: error recoring successful login"
+ return done(err)
+ logger.log "smoke test: clearing rate limit "
require("../../../app/js/infrastructure/RateLimiter.js").clearRateLimit "open-project", "#{Settings.smokeTest.projectId}:#{Settings.smokeTest.userId}", ->
+ logger.log "smoke test: hitting /register"
command = """
curl -H "X-Forwarded-Proto: https" -c #{cookeFilePath} #{buildUrl('register')}
"""
@@ -37,17 +43,20 @@ describe "Opening", ->
logger.err stdout:stdout, "smoke test: does not have csrf token"
return done("smoke test: does not have csrf token")
csrf = csrfMatches[1]
-
+ logger.log "smoke test: converting cookie file 1"
convertCookieFile (err) ->
return done(err) if err?
+ logger.log "smoke test: hitting /register with csrf"
command = """
curl -c #{cookeFilePath} -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -d '{"_csrf":"#{csrf}", "email":"#{Settings.smokeTest.user}", "password":"#{Settings.smokeTest.password}"}' #{buildUrl('register')}
"""
child.exec command, (err) ->
return done(err) if err?
+ logger.log "smoke test: finishing setup"
convertCookieFile done
- after (done)->
+ after (done)->
+ logger.log "smoke test: cleaning up"
command = """
curl -H "X-Forwarded-Proto: https" -c #{cookeFilePath} #{buildUrl('logout')}
"""
@@ -57,6 +66,7 @@ describe "Opening", ->
fs.unlink cookeFilePath, done
it "a project", (done) ->
+ logger.log "smoke test: Checking can load a project"
@timeout(4000)
command = """
curl -H "X-Forwarded-Proto: https" -v #{buildUrl("project/#{Settings.smokeTest.projectId}")}
@@ -74,6 +84,7 @@ describe "Opening", ->
it "the project list", (done) ->
+ logger.log "smoke test: Checking can load project list"
@timeout(4000)
command = """
curl -H "X-Forwarded-Proto: https" -v #{buildUrl("project")}