Commit 927433f5 by gradyward

Merge branch 'authoring' of https://github.com/edx/edx-ora2 into…

Merge branch 'authoring' of https://github.com/edx/edx-ora2 into grady/student-training-authoring-templates

Conflicts:
	openassessment/xblock/studio_mixin.py
parents b647d067 e132d976
{% load i18n %} {% load i18n %}
{% load tz %}
{% spaceless %} {% spaceless %}
<div id="openassessment-editor" class="editor-with-buttons editor-with-tabs"> <div id="openassessment-editor" class="editor-with-buttons editor-with-tabs">
<div class="openassessment_editor_content_and_tabs"> <div class="openassessment_editor_content_and_tabs">
...@@ -30,15 +31,59 @@ ...@@ -30,15 +31,59 @@
</li> </li>
<li class="openassessment_date_editor field comp-setting-entry"> <li class="openassessment_date_editor field comp-setting-entry">
<div class="wrapper-comp-setting"> <div class="wrapper-comp-setting">
<label for="openassessment_submission_start_editor" class="setting-label">{% trans "Response Submission Start Date"%} </label> <label
<input type="datetime-local" class="input setting-input" id="openassessment_submission_start_editor" value="{{ submission_start }}"> for="openassessment_submission_start_date"
class="setting-label">
{% trans "Submission Start Date" %}
</label>
<input
type="text"
class="input setting-input"
id="openassessment_submission_start_date"
value="{{ submission_start|utc|date:"y-m-d" }}"
>
</div>
<div class="wrapper-comp-setting">
<label
for="openassessment_submission_start_time"
class="setting-label">
{% trans "Submission Start Time" %}
</label>
<input
type="text"
class="input setting-input"
id="openassessment_submission_start_time"
value="{{ submission_start|utc|date:"H:i" }}"
>
</div> </div>
<p class="setting-help">{% trans "The date at which submissions will first be accepted." %}</p> <p class="setting-help">{% trans "The date at which submissions will first be accepted." %}</p>
</li> </li>
<li class="openassessment_date_editor field comp-setting-entry"> <li class="openassessment_date_editor field comp-setting-entry">
<div class="wrapper-comp-setting"> <div class="wrapper-comp-setting">
<label for="openassessment_submission_due_editor" class="setting-label">{% trans "Response Submission Due Date" %}</label> <label
<input type="datetime-local" class="input setting-input" id="openassessment_submission_due_editor" value="{{ submission_due }}"> for="openassessment_submission_due_date"
class="setting-label">
{% trans "Submission Due Date" %}
</label>
<input
type="text"
class="input setting-input"
id="openassessment_submission_due_date"
value="{{ submission_due|utc|date:"y-m-d" }}"
>
</div>
<div class="wrapper-comp-setting">
<label
for="openassessment_submission_due_time"
class="setting-label">
{% trans "Submission Due Time" %}
</label>
<input
type="text"
class="input setting-input"
id="openassessment_submission_due_time"
value="{{ submission_due|utc|date:"H:i" }}"
>
</div> </div>
<p class="setting-help">{% trans "The date at which submissions will stop being accepted." %}</p> <p class="setting-help">{% trans "The date at which submissions will stop being accepted." %}</p>
</li> </li>
......
{% load i18n %} {% load i18n %}
{% load tz %}
{% spaceless %} {% spaceless %}
<li class="openassessment_assessment_module_settings_editor" id="oa_peer_assessment_editor"> <li class="openassessment_assessment_module_settings_editor" id="oa_peer_assessment_editor">
<div class = "drag-handle action"></div> <div class = "drag-handle action"></div>
...@@ -33,16 +34,44 @@ ...@@ -33,16 +34,44 @@
<li class="field comp-setting-entry"> <li class="field comp-setting-entry">
<div class="wrapper-comp-setting"> <div class="wrapper-comp-setting">
<label for="peer_assessment_start_date" class="setting-label">{% trans "Start Date" %}</label> <label for="peer_assessment_start_date" class="setting-label">{% trans "Start Date" %}</label>
<input id="peer_assessment_start_date" type="datetime-local" class="input setting-input" value="{{ assessments.peer_assessment.start }}"> <input
id="peer_assessment_start_date"
type="text"
class="input setting-input"
value="{{ assessments.peer_assessment.start|utc|date:"Y-m-d" }}"
>
</div> </div>
<p class="setting-help">{% trans "If desired, specify a start date for the peer assessment period. If no date is specified, peer assessment can begin when submissions begin."%}</p> <div class="wrapper-comp-setting">
<label for="peer_assessment_start_time" class="setting-label">{% trans "Start Time" %}</label>
<input
id="peer_assessment_start_time"
type="text"
class="input setting-input"
value="{{ assessments.peer_assessment.start|utc|date:"H:i" }}"
>
</div>
<p class="setting-help">{% trans "Specify a start date for the peer assessment period." %}</p>
</li> </li>
<li class="field comp-setting-entry"> <li class="field comp-setting-entry">
<div class="wrapper-comp-setting"> <div class="wrapper-comp-setting">
<label for="peer_assessment_due_date" class="setting-label">{% trans "Due Date" %}</label> <label for="peer_assessment_due_date" class="setting-label">{% trans "Due Date" %}</label>
<input id="peer_assessment_due_date" type="datetime-local" class="input setting-input" value="{{ assessments.peer_assessment.due }}"> <input
id="peer_assessment_due_date"
type="text"
class="input setting-input"
value="{{ assessments.peer_assessment.due|utc|date:"Y-m-d" }}"
>
</div>
<div class="wrapper-comp-setting">
<label for="peer_assessment_due_time" class="setting-label">{% trans "Due Time" %}</label>
<input
id="peer_assessment_due_time"
type="text"
class="input setting-input"
value="{{ assessments.peer_assessment.due|utc|date:"H:i" }}"
>
</div> </div>
<p class="setting-help">{% trans "If desired, specify a due date for the peer assessment period. If no date is specified, peer assessment can run as long as the problem is open."%}</p> <p class="setting-help">{% trans "Specify a due date for the peer assessment period." %}</p>
</li> </li>
</ul> </ul>
</div> </div>
......
{% load i18n %} {% load i18n %}
{% load tz %}
{% spaceless %} {% spaceless %}
<li class="openassessment_assessment_module_settings_editor" id="oa_self_assessment_editor"> <li class="openassessment_assessment_module_settings_editor" id="oa_self_assessment_editor">
<div class = "drag-handle action"></div> <div class = "drag-handle action"></div>
...@@ -19,16 +20,44 @@ ...@@ -19,16 +20,44 @@
<li class="field comp-setting-entry"> <li class="field comp-setting-entry">
<div class="wrapper-comp-setting"> <div class="wrapper-comp-setting">
<label for="self_assessment_start_date" class="setting-label">{% trans "Start Date" %}</label> <label for="self_assessment_start_date" class="setting-label">{% trans "Start Date" %}</label>
<input id="self_assessment_start_date" type="datetime-local" class="input setting-input" value="{{ assessments.self_assessment.start }}"> <input
id="self_assessment_start_date"
type="text"
class="input setting-input"
value="{{ assessments.self_assessment.start|utc|date:"Y-m-d" }}"
>
</div> </div>
<p class="setting-help">{% trans "If desired, specify a start date for the self assessment period. If no date is specified, self assessment can begin when submissions begin."%}</p> <div class="wrapper-comp-setting">
<label for="self_assessment_start_time" class="setting-label">{% trans "Start Time" %}</label>
<input
id="self_assessment_start_time"
type="text"
class="input setting-input"
value="{{ assessments.self_assessment.start|utc|date:"H:i" }}"
>
</div>
<p class="setting-help">{% trans "Specify a start date for the self assessment period." %}</p>
</li> </li>
<li class="field comp-setting-entry"> <li class="field comp-setting-entry">
<div class="wrapper-comp-setting"> <div class="wrapper-comp-setting">
<label for="self_assessment_due_date" class="setting-label">{% trans "Due Date" %}</label> <label for="self_assessment_due_date" class="setting-label">{% trans "Due Date" %}</label>
<input id="self_assessment_due_date" type="datetime-local" class="input setting-input" value="{{ assessments.self_assessment.due }}"> <input
id="self_assessment_due_date"
type="text"
class="input setting-input"
value="{{ assessments.self_assessment.due|utc|date:"Y-m-d" }}"
>
</div>
<div class="wrapper-comp-setting">
<label for="self_assessment_due_time" class="setting-label">{% trans "Due Time" %}</label>
<input
id="self_assessment_due_time"
type="text"
class="input setting-input"
value="{{ assessments.self_assessment.due|utc|date:"H:i" }}"
>
</div> </div>
<p class="setting-help">{% trans "If desired, specify a due date for the self assessment period. If no date is specified, self assessment can run as long as the problem is open."%}</p> <p class="setting-help">{% trans "Specify a due date for the self assessment period." %}</p>
</li> </li>
</ul> </ul>
</div> </div>
......
...@@ -16,61 +16,8 @@ ...@@ -16,61 +16,8 @@
{% trans "Enter one or more sample responses that you've created, together with the scores you would give those responses. Be sure to format the responses and scores according to the placeholder text below." %} {% trans "Enter one or more sample responses that you've created, together with the scores you would give those responses. Be sure to format the responses and scores according to the placeholder text below." %}
</p> </p>
<ol> <ol>
{% for example in assessments.training.examples%} {% for example in assessments.training.examples %}
<li class="openassessment_training_example is-collapsible"> {% include "openassessmentblock/edit/oa_training_example.html" with example=example %}
<div class="openassessment_training_example_header view-outline">
<a class="action expand-collapse collapse">
<i class="icon-caret-down ui-toggle-expansion"></i>
</a>
<h6 class="openassessment_training_example_header_title">
{% blocktrans %} Scored Response {% endblocktrans %}
</h6>
<div class="openassessment_training_example_remove">
<h2>{% trans "Remove" %}</h2>
</div>
</div>
<div class="openassessment_training_example_body">
<div class="openassessment_training_example_scored_rubric wrapper-comp-settings">
<h2>{% trans "Scored Rubric" %}</h2>
<ol class="openassessment_training_example_criteria_selections list-input settings-list">
{% for criterion in criteria %}
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label class="openassessment_training_example_criterion_name setting-label">
{{criterion.name}}
<select class="openassessment_training_example_criterion_option setting-input">
<option value="Not Scored">{% trans "Not Scored" %}</option>
{% for option in criterion.options %}
<option value={{option.name}}
{% for opt_sel in example.options_selected %}
{% if opt_sel.criterion == criterion.name and opt_sel.option == option.name %}
selected
{% endif %}
{% endfor %}
>
{{option.name}} - {{option.points}} {% trans "points" %}
</option>
{% endfor %}
</select>
</label>
</div>
</li>
{% endfor %}
</ol>
</div>
<div class="openassessment_training_example_essay_wrapper">
<h2>
{% trans "Response" %}
</h2>
<textarea class="openassessment_training_example_essay">
{{example.answer}}
</textarea>
</div>
</div>
</li>
{% endfor %} {% endfor %}
</ol> </ol>
<div> <div>
...@@ -80,4 +27,8 @@ ...@@ -80,4 +27,8 @@
</div> </div>
</div> </div>
</li> </li>
<div id="openassessment_training_example_template" class="is--hidden">
{% include "openassessmentblock/edit/oa_training_example.html" with example=assessments.training.template %}
</div>
{% endspaceless %} {% endspaceless %}
\ No newline at end of file
{% load i18n %}
{% spaceless %}
<li class="openassessment_training_example is-collapsible">
<div class="openassessment_training_example_header view-outline">
<a class="action expand-collapse collapse">
<i class="icon-caret-down ui-toggle-expansion"></i>
</a>
<h6 class="openassessment_training_example_header_title">
{% blocktrans %} Scored Response {% endblocktrans %}
</h6>
<div class="openassessment_training_example_remove">
<h2>{% trans "Remove" %}</h2>
</div>
</div>
<div class="openassessment_training_example_body">
<div class="openassessment_training_example_scored_rubric wrapper-comp-settings">
<h2>{% trans "Scored Rubric" %}</h2>
<ol class="openassessment_training_example_criteria_selections list-input settings-list">
{% for criterion in example.criteria %}
<li class="field comp-setting-entry">
<div class="wrapper-comp-setting">
<label class="openassessment_training_example_criterion_name setting-label">
{{criterion.name}}
<select class="openassessment_training_example_criterion_option setting-input">
<option value="Not Scored">{% trans "Not Scored" %}</option>
{% for option in criterion.options %}
<option value={{option.name}}
{% if criterion.option_selected == option.name %} selected {% endif %}
>
{{option.name}} - {{option.points}} {% trans "points" %}
</option>
{% endfor %}
</select>
</label>
</div>
</li>
{% endfor %}
</ol>
</div>
<div class="openassessment_training_example_essay_wrapper">
<h2>{% trans "Response" %}</h2>
<textarea class="openassessment_training_example_essay">{{example.answer}}</textarea>
</div>
</div>
</li>
{% endspaceless %}
\ No newline at end of file
...@@ -5,7 +5,6 @@ Schema for validating and sanitizing data received from the JavaScript client. ...@@ -5,7 +5,6 @@ Schema for validating and sanitizing data received from the JavaScript client.
import dateutil import dateutil
from pytz import utc from pytz import utc
from voluptuous import Schema, Required, All, Any, Range, In, Invalid from voluptuous import Schema, Required, All, Any, Range, In, Invalid
from openassessment.xblock.xml import parse_examples_xml_str, UpdateFromXmlError
def utf8_validator(value): def utf8_validator(value):
...@@ -57,25 +56,6 @@ def datetime_validator(value): ...@@ -57,25 +56,6 @@ def datetime_validator(value):
raise Invalid(u"Could not parse datetime from value \"{val}\"".format(val=value)) raise Invalid(u"Could not parse datetime from value \"{val}\"".format(val=value))
def examples_xml_validator(value):
"""Parse and validate student training examples XML.
Args:
value: The value to parse.
Returns:
list of training examples, serialized as dictionaries.
Raises:
Invalid
"""
try:
return parse_examples_xml_str(value)
except UpdateFromXmlError:
raise Invalid(u"Could not parse examples from XML")
# Schema definition for an update from the Studio JavaScript editor. # Schema definition for an update from the Studio JavaScript editor.
EDITOR_UPDATE_SCHEMA = Schema({ EDITOR_UPDATE_SCHEMA = Schema({
Required('prompt'): utf8_validator, Required('prompt'): utf8_validator,
...@@ -98,7 +78,17 @@ EDITOR_UPDATE_SCHEMA = Schema({ ...@@ -98,7 +78,17 @@ EDITOR_UPDATE_SCHEMA = Schema({
Required('due', default=None): Any(datetime_validator, None), Required('due', default=None): Any(datetime_validator, None),
'must_grade': All(int, Range(min=0)), 'must_grade': All(int, Range(min=0)),
'must_be_graded_by': All(int, Range(min=0)), 'must_be_graded_by': All(int, Range(min=0)),
'examples': All(utf8_validator, examples_xml_validator) 'examples': [
Schema({
Required('answer'): utf8_validator,
Required('options_selected'): [
Schema({
Required('criterion'): utf8_validator,
Required('option'): utf8_validator
})
]
})
]
}) })
], ],
Required('feedbackprompt', default=u""): utf8_validator, Required('feedbackprompt', default=u""): utf8_validator,
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -437,7 +437,8 @@ ...@@ -437,7 +437,8 @@
], ],
"assessments": { "assessments": {
"peer_assessment": { "peer_assessment": {
"start": "2014-10-04T00:00:00", "start": "",
"due": "",
"must_grade": 5, "must_grade": 5,
"must_be_graded_by": 3 "must_be_graded_by": 3
}, },
......
/*! jQuery UI - v1.10.4 - 2014-07-07
* http://jqueryui.com
* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.sortable.js, jquery.ui.tabs.js
* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
(function(e,t){function i(t,i){var a,n,o,r=t.nodeName.toLowerCase();return"area"===r?(a=t.parentNode,n=a.name,t.href&&n&&"map"===a.nodeName.toLowerCase()?(o=e("img[usemap=#"+n+"]")[0],!!o&&s(o)):!1):(/input|select|textarea|button|object/.test(r)?!t.disabled:"a"===r?t.href||i:i)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var a=0,n=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.4",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var s,a,n=e(this[0]);n.length&&n[0]!==document;){if(s=n.css("position"),("absolute"===s||"relative"===s||"fixed"===s)&&(a=parseInt(n.css("zIndex"),10),!isNaN(a)&&0!==a))return a;n=n.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++a)})},removeUniqueId:function(){return this.each(function(){n.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var s=e.attr(t,"tabindex"),a=isNaN(s);return(a||s>=0)&&i(t,!a)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(i,s){function a(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===s?["Left","Right"]:["Top","Bottom"],o=s.toLowerCase(),r={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+s]=function(i){return i===t?r["inner"+s].call(this):this.each(function(){e(this).css(o,a(this,i)+"px")})},e.fn["outer"+s]=function(t,i){return"number"!=typeof t?r["outer"+s].call(this,t):this.each(function(){e(this).css(o,a(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,s){var a,n=e.ui[t].prototype;for(a in s)n.plugins[a]=n.plugins[a]||[],n.plugins[a].push([i,s[a]])},call:function(e,t,i){var s,a=e.plugins[t];if(a&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(s=0;a.length>s;s++)e.options[a[s][0]]&&a[s][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",a=!1;return t[s]>0?!0:(t[s]=1,a=t[s]>0,t[s]=0,a)}})})(jQuery);(function(e,t){var i=0,s=Array.prototype.slice,a=e.cleanData;e.cleanData=function(t){for(var i,s=0;null!=(i=t[s]);s++)try{e(i).triggerHandler("remove")}catch(n){}a(t)},e.widget=function(i,s,a){var n,r,o,h,l={},u=i.split(".")[0];i=i.split(".")[1],n=u+"-"+i,a||(a=s,s=e.Widget),e.expr[":"][n.toLowerCase()]=function(t){return!!e.data(t,n)},e[u]=e[u]||{},r=e[u][i],o=e[u][i]=function(e,i){return this._createWidget?(arguments.length&&this._createWidget(e,i),t):new o(e,i)},e.extend(o,r,{version:a.version,_proto:e.extend({},a),_childConstructors:[]}),h=new s,h.options=e.widget.extend({},h.options),e.each(a,function(i,a){return e.isFunction(a)?(l[i]=function(){var e=function(){return s.prototype[i].apply(this,arguments)},t=function(e){return s.prototype[i].apply(this,e)};return function(){var i,s=this._super,n=this._superApply;return this._super=e,this._superApply=t,i=a.apply(this,arguments),this._super=s,this._superApply=n,i}}(),t):(l[i]=a,t)}),o.prototype=e.widget.extend(h,{widgetEventPrefix:r?h.widgetEventPrefix||i:i},l,{constructor:o,namespace:u,widgetName:i,widgetFullName:n}),r?(e.each(r._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete r._childConstructors):s._childConstructors.push(o),e.widget.bridge(i,o)},e.widget.extend=function(i){for(var a,n,r=s.call(arguments,1),o=0,h=r.length;h>o;o++)for(a in r[o])n=r[o][a],r[o].hasOwnProperty(a)&&n!==t&&(i[a]=e.isPlainObject(n)?e.isPlainObject(i[a])?e.widget.extend({},i[a],n):e.widget.extend({},n):n);return i},e.widget.bridge=function(i,a){var n=a.prototype.widgetFullName||i;e.fn[i]=function(r){var o="string"==typeof r,h=s.call(arguments,1),l=this;return r=!o&&h.length?e.widget.extend.apply(null,[r].concat(h)):r,o?this.each(function(){var s,a=e.data(this,n);return a?e.isFunction(a[r])&&"_"!==r.charAt(0)?(s=a[r].apply(a,h),s!==a&&s!==t?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):t):e.error("no such method '"+r+"' for "+i+" widget instance"):e.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+r+"'")}):this.each(function(){var t=e.data(this,n);t?t.option(r||{})._init():e.data(this,n,new a(r,this))}),l}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,s){s=e(s||this.defaultElement||this)[0],this.element=e(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),s!==this&&(e.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===s&&this.destroy()}}),this.document=e(s.style?s.ownerDocument:s.document||s),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(i,s){var a,n,r,o=i;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof i)if(o={},a=i.split("."),i=a.shift(),a.length){for(n=o[i]=e.widget.extend({},this.options[i]),r=0;a.length-1>r;r++)n[a[r]]=n[a[r]]||{},n=n[a[r]];if(i=a.pop(),1===arguments.length)return n[i]===t?null:n[i];n[i]=s}else{if(1===arguments.length)return this.options[i]===t?null:this.options[i];o[i]=s}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,a){var n,r=this;"boolean"!=typeof i&&(a=s,s=i,i=!1),a?(s=n=e(s),this.bindings=this.bindings.add(s)):(a=s,s=this.element,n=this.widget()),e.each(a,function(a,o){function h(){return i||r.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?r[o]:o).apply(r,arguments):t}"string"!=typeof o&&(h.guid=o.guid=o.guid||h.guid||e.guid++);var l=a.match(/^(\w+)\s*(.*)$/),u=l[1]+r.eventNamespace,d=l[2];d?n.delegate(d,u,h):s.bind(u,h)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var a,n,r=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],n=i.originalEvent)for(a in n)a in i||(i[a]=n[a]);return this.element.trigger(i,s),!(e.isFunction(r)&&r.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,a,n){"string"==typeof a&&(a={effect:a});var r,o=a?a===!0||"number"==typeof a?i:a.effect||i:t;a=a||{},"number"==typeof a&&(a={duration:a}),r=!e.isEmptyObject(a),a.complete=n,a.delay&&s.delay(a.delay),r&&e.effects&&e.effects.effect[o]?s[t](a):o!==t&&s[o]?s[o](a.duration,a.easing,n):s.queue(function(i){e(this)[t](),n&&n.call(s[0]),i()})}})})(jQuery);(function(e){var t=!1;e(document).mouseup(function(){t=!1}),e.widget("ui.mouse",{version:"1.10.4",options:{cancel:"input,textarea,button,select,option",distance:1,delay:0},_mouseInit:function(){var t=this;this.element.bind("mousedown."+this.widgetName,function(e){return t._mouseDown(e)}).bind("click."+this.widgetName,function(i){return!0===e.data(i.target,t.widgetName+".preventClickEvent")?(e.removeData(i.target,t.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):undefined}),this.started=!1},_mouseDestroy:function(){this.element.unbind("."+this.widgetName),this._mouseMoveDelegate&&e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(i){if(!t){this._mouseStarted&&this._mouseUp(i),this._mouseDownEvent=i;var s=this,a=1===i.which,n="string"==typeof this.options.cancel&&i.target.nodeName?e(i.target).closest(this.options.cancel).length:!1;return a&&!n&&this._mouseCapture(i)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){s.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(i)&&this._mouseDelayMet(i)&&(this._mouseStarted=this._mouseStart(i)!==!1,!this._mouseStarted)?(i.preventDefault(),!0):(!0===e.data(i.target,this.widgetName+".preventClickEvent")&&e.removeData(i.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(e){return s._mouseMove(e)},this._mouseUpDelegate=function(e){return s._mouseUp(e)},e(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate),i.preventDefault(),t=!0,!0)):!0}},_mouseMove:function(t){return e.ui.ie&&(!document.documentMode||9>document.documentMode)&&!t.button?this._mouseUp(t):this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}})})(jQuery);(function(e,t){function i(e,t,i){return[parseFloat(e[0])*(p.test(e[0])?t/100:1),parseFloat(e[1])*(p.test(e[1])?i/100:1)]}function s(t,i){return parseInt(e.css(t,i),10)||0}function a(t){var i=t[0];return 9===i.nodeType?{width:t.width(),height:t.height(),offset:{top:0,left:0}}:e.isWindow(i)?{width:t.width(),height:t.height(),offset:{top:t.scrollTop(),left:t.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:t.outerWidth(),height:t.outerHeight(),offset:t.offset()}}e.ui=e.ui||{};var n,r=Math.max,o=Math.abs,h=Math.round,l=/left|center|right/,u=/top|center|bottom/,d=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,p=/%$/,m=e.fn.position;e.position={scrollbarWidth:function(){if(n!==t)return n;var i,s,a=e("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),r=a.children()[0];return e("body").append(a),i=r.offsetWidth,a.css("overflow","scroll"),s=r.offsetWidth,i===s&&(s=a[0].clientWidth),a.remove(),n=i-s},getScrollInfo:function(t){var i=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),s=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),a="scroll"===i||"auto"===i&&t.width<t.element[0].scrollWidth,n="scroll"===s||"auto"===s&&t.height<t.element[0].scrollHeight;return{width:n?e.position.scrollbarWidth():0,height:a?e.position.scrollbarWidth():0}},getWithinInfo:function(t){var i=e(t||window),s=e.isWindow(i[0]),a=!!i[0]&&9===i[0].nodeType;return{element:i,isWindow:s,isDocument:a,offset:i.offset()||{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:s?i.width():i.outerWidth(),height:s?i.height():i.outerHeight()}}},e.fn.position=function(t){if(!t||!t.of)return m.apply(this,arguments);t=e.extend({},t);var n,p,f,g,v,y,b=e(t.of),_=e.position.getWithinInfo(t.within),x=e.position.getScrollInfo(_),k=(t.collision||"flip").split(" "),w={};return y=a(b),b[0].preventDefault&&(t.at="left top"),p=y.width,f=y.height,g=y.offset,v=e.extend({},g),e.each(["my","at"],function(){var e,i,s=(t[this]||"").split(" ");1===s.length&&(s=l.test(s[0])?s.concat(["center"]):u.test(s[0])?["center"].concat(s):["center","center"]),s[0]=l.test(s[0])?s[0]:"center",s[1]=u.test(s[1])?s[1]:"center",e=d.exec(s[0]),i=d.exec(s[1]),w[this]=[e?e[0]:0,i?i[0]:0],t[this]=[c.exec(s[0])[0],c.exec(s[1])[0]]}),1===k.length&&(k[1]=k[0]),"right"===t.at[0]?v.left+=p:"center"===t.at[0]&&(v.left+=p/2),"bottom"===t.at[1]?v.top+=f:"center"===t.at[1]&&(v.top+=f/2),n=i(w.at,p,f),v.left+=n[0],v.top+=n[1],this.each(function(){var a,l,u=e(this),d=u.outerWidth(),c=u.outerHeight(),m=s(this,"marginLeft"),y=s(this,"marginTop"),T=d+m+s(this,"marginRight")+x.width,D=c+y+s(this,"marginBottom")+x.height,S=e.extend({},v),N=i(w.my,u.outerWidth(),u.outerHeight());"right"===t.my[0]?S.left-=d:"center"===t.my[0]&&(S.left-=d/2),"bottom"===t.my[1]?S.top-=c:"center"===t.my[1]&&(S.top-=c/2),S.left+=N[0],S.top+=N[1],e.support.offsetFractions||(S.left=h(S.left),S.top=h(S.top)),a={marginLeft:m,marginTop:y},e.each(["left","top"],function(i,s){e.ui.position[k[i]]&&e.ui.position[k[i]][s](S,{targetWidth:p,targetHeight:f,elemWidth:d,elemHeight:c,collisionPosition:a,collisionWidth:T,collisionHeight:D,offset:[n[0]+N[0],n[1]+N[1]],my:t.my,at:t.at,within:_,elem:u})}),t.using&&(l=function(e){var i=g.left-S.left,s=i+p-d,a=g.top-S.top,n=a+f-c,h={target:{element:b,left:g.left,top:g.top,width:p,height:f},element:{element:u,left:S.left,top:S.top,width:d,height:c},horizontal:0>s?"left":i>0?"right":"center",vertical:0>n?"top":a>0?"bottom":"middle"};d>p&&p>o(i+s)&&(h.horizontal="center"),c>f&&f>o(a+n)&&(h.vertical="middle"),h.important=r(o(i),o(s))>r(o(a),o(n))?"horizontal":"vertical",t.using.call(this,e,h)}),u.offset(e.extend(S,{using:l}))})},e.ui.position={fit:{left:function(e,t){var i,s=t.within,a=s.isWindow?s.scrollLeft:s.offset.left,n=s.width,o=e.left-t.collisionPosition.marginLeft,h=a-o,l=o+t.collisionWidth-n-a;t.collisionWidth>n?h>0&&0>=l?(i=e.left+h+t.collisionWidth-n-a,e.left+=h-i):e.left=l>0&&0>=h?a:h>l?a+n-t.collisionWidth:a:h>0?e.left+=h:l>0?e.left-=l:e.left=r(e.left-o,e.left)},top:function(e,t){var i,s=t.within,a=s.isWindow?s.scrollTop:s.offset.top,n=t.within.height,o=e.top-t.collisionPosition.marginTop,h=a-o,l=o+t.collisionHeight-n-a;t.collisionHeight>n?h>0&&0>=l?(i=e.top+h+t.collisionHeight-n-a,e.top+=h-i):e.top=l>0&&0>=h?a:h>l?a+n-t.collisionHeight:a:h>0?e.top+=h:l>0?e.top-=l:e.top=r(e.top-o,e.top)}},flip:{left:function(e,t){var i,s,a=t.within,n=a.offset.left+a.scrollLeft,r=a.width,h=a.isWindow?a.scrollLeft:a.offset.left,l=e.left-t.collisionPosition.marginLeft,u=l-h,d=l+t.collisionWidth-r-h,c="left"===t.my[0]?-t.elemWidth:"right"===t.my[0]?t.elemWidth:0,p="left"===t.at[0]?t.targetWidth:"right"===t.at[0]?-t.targetWidth:0,m=-2*t.offset[0];0>u?(i=e.left+c+p+m+t.collisionWidth-r-n,(0>i||o(u)>i)&&(e.left+=c+p+m)):d>0&&(s=e.left-t.collisionPosition.marginLeft+c+p+m-h,(s>0||d>o(s))&&(e.left+=c+p+m))},top:function(e,t){var i,s,a=t.within,n=a.offset.top+a.scrollTop,r=a.height,h=a.isWindow?a.scrollTop:a.offset.top,l=e.top-t.collisionPosition.marginTop,u=l-h,d=l+t.collisionHeight-r-h,c="top"===t.my[1],p=c?-t.elemHeight:"bottom"===t.my[1]?t.elemHeight:0,m="top"===t.at[1]?t.targetHeight:"bottom"===t.at[1]?-t.targetHeight:0,f=-2*t.offset[1];0>u?(s=e.top+p+m+f+t.collisionHeight-r-n,e.top+p+m+f>u&&(0>s||o(u)>s)&&(e.top+=p+m+f)):d>0&&(i=e.top-t.collisionPosition.marginTop+p+m+f-h,e.top+p+m+f>d&&(i>0||d>o(i))&&(e.top+=p+m+f))}},flipfit:{left:function(){e.ui.position.flip.left.apply(this,arguments),e.ui.position.fit.left.apply(this,arguments)},top:function(){e.ui.position.flip.top.apply(this,arguments),e.ui.position.fit.top.apply(this,arguments)}}},function(){var t,i,s,a,n,r=document.getElementsByTagName("body")[0],o=document.createElement("div");t=document.createElement(r?"div":"body"),s={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},r&&e.extend(s,{position:"absolute",left:"-1000px",top:"-1000px"});for(n in s)t.style[n]=s[n];t.appendChild(o),i=r||document.documentElement,i.insertBefore(t,i.firstChild),o.style.cssText="position: absolute; left: 10.7432222px;",a=e(o).offset().left,e.support.offsetFractions=a>10&&11>a,t.innerHTML="",i.removeChild(t)}()})(jQuery);(function(e){function t(e,t,i){return e>t&&t+i>e}function i(e){return/left|right/.test(e.css("float"))||/inline|table-cell/.test(e.css("display"))}e.widget("ui.sortable",e.ui.mouse,{version:"1.10.4",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?"x"===e.axis||i(this.items[0].item):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,i){"disabled"===t?(this.options[t]=i,this.widget().toggleClass("ui-sortable-disabled",!!i)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,i){var s=null,a=!1,n=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(t),e(t.target).parents().each(function(){return e.data(this,n.widgetName+"-item")===n?(s=e(this),!1):undefined}),e.data(t.target,n.widgetName+"-item")===n&&(s=e(t.target)),s?!this.options.handle||i||(e(this.options.handle,s).find("*").addBack().each(function(){this===t.target&&(a=!0)}),a)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(t,i,s){var a,n,r=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,r.cursorAt&&this._adjustOffsetFromHelper(r.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),r.containment&&this._setContainment(),r.cursor&&"auto"!==r.cursor&&(n=this.document.find("body"),this.storedCursor=n.css("cursor"),n.css("cursor",r.cursor),this.storedStylesheet=e("<style>*{ cursor: "+r.cursor+" !important; }</style>").appendTo(n)),r.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",r.opacity)),r.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",r.zIndex)),this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(a=this.containers.length-1;a>=0;a--)this.containers[a]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!r.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){var i,s,a,n,r=this.options,o=!1;for(this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==document&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY<r.scrollSensitivity?this.scrollParent[0].scrollTop=o=this.scrollParent[0].scrollTop+r.scrollSpeed:t.pageY-this.overflowOffset.top<r.scrollSensitivity&&(this.scrollParent[0].scrollTop=o=this.scrollParent[0].scrollTop-r.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-t.pageX<r.scrollSensitivity?this.scrollParent[0].scrollLeft=o=this.scrollParent[0].scrollLeft+r.scrollSpeed:t.pageX-this.overflowOffset.left<r.scrollSensitivity&&(this.scrollParent[0].scrollLeft=o=this.scrollParent[0].scrollLeft-r.scrollSpeed)):(t.pageY-e(document).scrollTop()<r.scrollSensitivity?o=e(document).scrollTop(e(document).scrollTop()-r.scrollSpeed):e(window).height()-(t.pageY-e(document).scrollTop())<r.scrollSensitivity&&(o=e(document).scrollTop(e(document).scrollTop()+r.scrollSpeed)),t.pageX-e(document).scrollLeft()<r.scrollSensitivity?o=e(document).scrollLeft(e(document).scrollLeft()-r.scrollSpeed):e(window).width()-(t.pageX-e(document).scrollLeft())<r.scrollSensitivity&&(o=e(document).scrollLeft(e(document).scrollLeft()+r.scrollSpeed))),o!==!1&&e.ui.ddmanager&&!r.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],a=s.item[0],n=this._intersectsWithPointer(s),n&&s.instance===this.currentContainer&&a!==this.currentItem[0]&&this.placeholder[1===n?"next":"prev"]()[0]!==a&&!e.contains(this.placeholder[0],a)&&("semi-dynamic"===this.options.type?!e.contains(this.element[0],a):!0)){if(this.direction=1===n?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,i){if(t){if(e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t),this.options.revert){var s=this,a=this.placeholder.offset(),n=this.options.axis,r={};n&&"x"!==n||(r.left=a.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollLeft)),n&&"y"!==n||(r.top=a.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===document.body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,e(this.helper).animate(r,parseInt(this.options.revert,10)||500,function(){s._clear(t)})}else this._clear(t,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp({target:null}),"original"===this.options.helper?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},e(i).each(function(){var i=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[\-=_](.+)/);i&&s.push((t.key||i[1]+"[]")+"="+(t.key&&t.expression?i[1]:i[2]))}),!s.length&&t.key&&s.push(t.key+"="),s.join("&")},toArray:function(t){var i=this._getItemsAsjQuery(t&&t.connected),s=[];return t=t||{},i.each(function(){s.push(e(t.item||this).attr(t.attribute||"id")||"")}),s},_intersectsWith:function(e){var t=this.positionAbs.left,i=t+this.helperProportions.width,s=this.positionAbs.top,a=s+this.helperProportions.height,n=e.left,r=n+e.width,o=e.top,h=o+e.height,l=this.offset.click.top,u=this.offset.click.left,d="x"===this.options.axis||s+l>o&&h>s+l,c="y"===this.options.axis||t+u>n&&r>t+u,p=d&&c;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>e[this.floating?"width":"height"]?p:t+this.helperProportions.width/2>n&&r>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>o&&h>a-this.helperProportions.height/2},_intersectsWithPointer:function(e){var i="x"===this.options.axis||t(this.positionAbs.top+this.offset.click.top,e.top,e.height),s="y"===this.options.axis||t(this.positionAbs.left+this.offset.click.left,e.left,e.width),a=i&&s,n=this._getDragVerticalDirection(),r=this._getDragHorizontalDirection();return a?this.floating?r&&"right"===r||"down"===n?2:1:n&&("down"===n?2:1):!1},_intersectsWithSides:function(e){var i=t(this.positionAbs.top+this.offset.click.top,e.top+e.height/2,e.height),s=t(this.positionAbs.left+this.offset.click.left,e.left+e.width/2,e.width),a=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&s||"left"===n&&!s:a&&("down"===a&&i||"up"===a&&!i)},_getDragVerticalDirection:function(){var e=this.positionAbs.top-this.lastPositionAbs.top;return 0!==e&&(e>0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return 0!==e&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor===String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){function i(){o.push(this)}var s,a,n,r,o=[],h=[],l=this._connectWith();if(l&&t)for(s=l.length-1;s>=0;s--)for(n=e(l[s]),a=n.length-1;a>=0;a--)r=e.data(n[a],this.widgetFullName),r&&r!==this&&!r.options.disabled&&h.push([e.isFunction(r.options.items)?r.options.items.call(r.element):e(r.options.items,r.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),r]);for(h.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return e(o)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var i=0;t.length>i;i++)if(t[i]===e.item[0])return!1;return!0})},_refreshItems:function(t){this.items=[],this.containers=[this];var i,s,a,n,r,o,h,l,u=this.items,d=[[e.isFunction(this.options.items)?this.options.items.call(this.element[0],t,{item:this.currentItem}):e(this.options.items,this.element),this]],c=this._connectWith();if(c&&this.ready)for(i=c.length-1;i>=0;i--)for(a=e(c[i]),s=a.length-1;s>=0;s--)n=e.data(a[s],this.widgetFullName),n&&n!==this&&!n.options.disabled&&(d.push([e.isFunction(n.options.items)?n.options.items.call(n.element[0],t,{item:this.currentItem}):e(n.options.items,n.element),n]),this.containers.push(n));for(i=d.length-1;i>=0;i--)for(r=d[i][1],o=d[i][0],s=0,l=o.length;l>s;s++)h=e(o[s]),h.data(this.widgetName+"-item",r),u.push({item:h,instance:r,width:0,height:0,left:0,top:0})},refreshPositions:function(t){this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,a,n;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(a=this.options.toleranceElement?e(this.options.toleranceElement,s.item):s.item,t||(s.width=a.outerWidth(),s.height=a.outerHeight()),n=a.offset(),s.left=n.left,s.top=n.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)n=this.containers[i].element.offset(),this.containers[i].containerCache.left=n.left,this.containers[i].containerCache.top=n.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(t){t=t||this;var i,s=t.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=t.currentItem[0].nodeName.toLowerCase(),a=e("<"+s+">",t.document[0]).addClass(i||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper");return"tr"===s?t.currentItem.children().each(function(){e("<td>&#160;</td>",t.document[0]).attr("colspan",e(this).attr("colspan")||1).appendTo(a)}):"img"===s&&a.attr("src",t.currentItem.attr("src")),i||a.css("visibility","hidden"),a},update:function(e,a){(!i||s.forcePlaceholderSize)&&(a.height()||a.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),a.width()||a.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10)))}}),t.placeholder=e(s.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),s.placeholder.update(t,t.placeholder)},_contactContainers:function(s){var a,n,r,o,h,l,u,d,c,p,m=null,f=null;for(a=this.containers.length-1;a>=0;a--)if(!e.contains(this.currentItem[0],this.containers[a].element[0]))if(this._intersectsWith(this.containers[a].containerCache)){if(m&&e.contains(this.containers[a].element[0],m.element[0]))continue;m=this.containers[a],f=a}else this.containers[a].containerCache.over&&(this.containers[a]._trigger("out",s,this._uiHash(this)),this.containers[a].containerCache.over=0);if(m)if(1===this.containers.length)this.containers[f].containerCache.over||(this.containers[f]._trigger("over",s,this._uiHash(this)),this.containers[f].containerCache.over=1);else{for(r=1e4,o=null,p=m.floating||i(this.currentItem),h=p?"left":"top",l=p?"width":"height",u=this.positionAbs[h]+this.offset.click[h],n=this.items.length-1;n>=0;n--)e.contains(this.containers[f].element[0],this.items[n].item[0])&&this.items[n].item[0]!==this.currentItem[0]&&(!p||t(this.positionAbs.top+this.offset.click.top,this.items[n].top,this.items[n].height))&&(d=this.items[n].item.offset()[h],c=!1,Math.abs(d-u)>Math.abs(d+this.items[n][l]-u)&&(c=!0,d+=this.items[n][l]),r>Math.abs(d-u)&&(r=Math.abs(d-u),o=this.items[n],this.direction=c?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[f])return;o?this._rearrange(s,o,null,!0):this._rearrange(s,null,this.containers[f].element,!0),this._trigger("change",s,this._uiHash()),this.containers[f]._trigger("change",s,this._uiHash(this)),this.currentContainer=this.containers[f],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[f]._trigger("over",s,this._uiHash(this)),this.containers[f].containerCache.over=1}},_createHelper:function(t){var i=this.options,s=e.isFunction(i.helper)?e(i.helper.apply(this.element[0],[t,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||e("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(t){"string"==typeof t&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===document.body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&e.ui.ie)&&(t={top:0,left:0}),{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var e=this.currentItem.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t,i,s,a=this.options;"parent"===a.containment&&(a.containment=this.helper[0].parentNode),("document"===a.containment||"window"===a.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,e("document"===a.containment?document:window).width()-this.helperProportions.width-this.margins.left,(e("document"===a.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(a.containment)||(t=e(a.containment)[0],i=e(a.containment).offset(),s="hidden"!==e(t).css("overflow"),this.containment=[i.left+(parseInt(e(t).css("borderLeftWidth"),10)||0)+(parseInt(e(t).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(e(t).css("borderTopWidth"),10)||0)+(parseInt(e(t).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(t.scrollWidth,t.offsetWidth):t.offsetWidth)-(parseInt(e(t).css("borderLeftWidth"),10)||0)-(parseInt(e(t).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(t.scrollHeight,t.offsetHeight):t.offsetHeight)-(parseInt(e(t).css("borderTopWidth"),10)||0)-(parseInt(e(t).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(t,i){i||(i=this.position);var s="absolute"===t?1:-1,a="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,n=/(html|body)/i.test(a[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():n?0:a.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():n?0:a.scrollLeft())*s}},_generatePosition:function(t){var i,s,a=this.options,n=t.pageX,r=t.pageY,o="absolute"!==this.cssPosition||this.scrollParent[0]!==document&&e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(o[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==document&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(t.pageX-this.offset.click.left<this.containment[0]&&(n=this.containment[0]+this.offset.click.left),t.pageY-this.offset.click.top<this.containment[1]&&(r=this.containment[1]+this.offset.click.top),t.pageX-this.offset.click.left>this.containment[2]&&(n=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(r=this.containment[3]+this.offset.click.top)),a.grid&&(i=this.originalPageY+Math.round((r-this.originalPageY)/a.grid[1])*a.grid[1],r=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-a.grid[1]:i+a.grid[1]:i,s=this.originalPageX+Math.round((n-this.originalPageX)/a.grid[0])*a.grid[0],n=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-a.grid[0]:s+a.grid[0]:s)),{top:r-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:o.scrollTop()),left:n-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:o.scrollLeft())}},_rearrange:function(e,t,i,s){i?i[0].appendChild(this.placeholder[0]):t.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?t.item[0]:t.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var a=this.counter;this._delay(function(){a===this.counter&&this.refreshPositions(!s)})},_clear:function(e,t){function i(e,t,i){return function(s){i._trigger(e,s,t._uiHash(t))}}this.reverting=!1;var s,a=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!t&&a.push(function(e){this._trigger("receive",e,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||t||a.push(function(e){this._trigger("update",e,this._uiHash())}),this!==this.currentContainer&&(t||(a.push(function(e){this._trigger("remove",e,this._uiHash())}),a.push(function(e){return function(t){e._trigger("receive",t,this._uiHash(this))}}.call(this,this.currentContainer)),a.push(function(e){return function(t){e._trigger("update",t,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)t||a.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(a.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,this.cancelHelperRemoval){if(!t){for(this._trigger("beforeStop",e,this._uiHash()),s=0;a.length>s;s++)a[s].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!1}if(t||this._trigger("beforeStop",e,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null,!t){for(s=0;a.length>s;s++)a[s].call(this,e);this._trigger("stop",e,this._uiHash())}return this.fromOutside=!1,!0},_trigger:function(){e.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(t){var i=t||this;return{helper:i.helper,placeholder:i.placeholder||e([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:t?t.element:null}}})})(jQuery);(function(e,t){function i(){return++a}function s(e){return e=e.cloneNode(!1),e.hash.length>1&&decodeURIComponent(e.href.replace(n,""))===decodeURIComponent(location.href.replace(n,""))}var a=0,n=/#.*$/;e.widget("ui.tabs",{version:"1.10.4",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs(),i.active=this._initialActive(),e.isArray(i.disabled)&&(i.disabled=e.unique(i.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):e(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var i=this.options.active,s=this.options.collapsible,a=location.hash.substring(1);return null===i&&(a&&this.tabs.each(function(s,n){return e(n).attr("aria-controls")===a?(i=s,!1):t}),null===i&&(i=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===i||-1===i)&&(i=this.tabs.length?0:!1)),i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),-1===i&&(i=s?!1:0)),!s&&i===!1&&this.anchors.length&&(i=0),i},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(i){var s=e(this.document[0].activeElement).closest("li"),a=this.tabs.index(s),n=!0;if(!this._handlePageNav(i)){switch(i.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:a++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:n=!1,a--;break;case e.ui.keyCode.END:a=this.anchors.length-1;break;case e.ui.keyCode.HOME:a=0;break;case e.ui.keyCode.SPACE:return i.preventDefault(),clearTimeout(this.activating),this._activate(a),t;case e.ui.keyCode.ENTER:return i.preventDefault(),clearTimeout(this.activating),this._activate(a===this.options.active?!1:a),t;default:return}i.preventDefault(),clearTimeout(this.activating),a=this._focusNextTab(a,n),i.ctrlKey||(s.attr("aria-selected","false"),this.tabs.eq(a).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",a)},this.delay))}},_panelKeydown:function(t){this._handlePageNav(t)||t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(i){return i.altKey&&i.keyCode===e.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):i.altKey&&i.keyCode===e.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):t},_findNextTab:function(t,i){function s(){return t>a&&(t=0),0>t&&(t=a),t}for(var a=this.tabs.length-1;-1!==e.inArray(s(),this.options.disabled);)t=i?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,i){return"active"===e?(this._activate(i),t):"disabled"===e?(this._setupDisabled(i),t):(this._super(e,i),"collapsible"===e&&(this.element.toggleClass("ui-tabs-collapsible",i),i||this.options.active!==!1||this._activate(0)),"event"===e&&this._setupEvents(i),"heightStyle"===e&&this._setupHeightStyle(i),t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,i=this.tablist.children(":has(a[href])");t.disabled=e.map(i.filter(".ui-state-disabled"),function(e){return i.index(e)}),this._processTabs(),t.active!==!1&&this.anchors.length?this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active):(t.active=!1,this.active=e()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(i,a){var n,r,o,h=e(a).uniqueId().attr("id"),l=e(a).closest("li"),u=l.attr("aria-controls");s(a)?(n=a.hash,r=t.element.find(t._sanitizeSelector(n))):(o=t._tabId(l),n="#"+o,r=t.element.find(n),r.length||(r=t._createPanel(o),r.insertAfter(t.panels[i-1]||t.tablist)),r.attr("aria-live","polite")),r.length&&(t.panels=t.panels.add(r)),u&&l.data("ui-tabs-aria-controls",u),l.attr({"aria-controls":n.substring(1),"aria-labelledby":h}),r.attr("aria-labelledby",h)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.tablist||this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("<div>").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var i,s=0;i=this.tabs[s];s++)t===!0||-1!==e.inArray(s,t)?e(i).addClass("ui-state-disabled").attr("aria-disabled","true"):e(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var i={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){i[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var i,s=this.element.parent();"fill"===t?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var t=e(this),s=t.css("position");"absolute"!==s&&"fixed"!==s&&(i-=t.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,i-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):"auto"===t&&(i=0,this.panels.each(function(){i=Math.max(i,e(this).height("").height())}).height(i))},_eventHandler:function(t){var i=this.options,s=this.active,a=e(t.currentTarget),n=a.closest("li"),r=n[0]===s[0],o=r&&i.collapsible,h=o?e():this._getPanelForTab(n),l=s.length?this._getPanelForTab(s):e(),u={oldTab:s,oldPanel:l,newTab:o?e():n,newPanel:h};t.preventDefault(),n.hasClass("ui-state-disabled")||n.hasClass("ui-tabs-loading")||this.running||r&&!i.collapsible||this._trigger("beforeActivate",t,u)===!1||(i.active=o?!1:this.tabs.index(n),this.active=r?e():n,this.xhr&&this.xhr.abort(),l.length||h.length||e.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(n),t),this._toggle(t,u))},_toggle:function(t,i){function s(){n.running=!1,n._trigger("activate",t,i)}function a(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&n.options.show?n._show(r,n.options.show,s):(r.show(),s())}var n=this,r=i.newPanel,o=i.oldPanel;this.running=!0,o.length&&this.options.hide?this._hide(o,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),a()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),o.hide(),a()),o.attr({"aria-expanded":"false","aria-hidden":"true"}),i.oldTab.attr("aria-selected","false"),r.length&&o.length?i.oldTab.attr("tabIndex",-1):r.length&&this.tabs.filter(function(){return 0===e(this).attr("tabIndex")}).attr("tabIndex",-1),r.attr({"aria-expanded":"true","aria-hidden":"false"}),i.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var i,s=this._findActive(t);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:e.noop}))},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),i=t.data("ui-tabs-aria-controls");i?t.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):t.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var s=this.options.disabled;s!==!1&&(i===t?s=!1:(i=this._getIndex(i),s=e.isArray(s)?e.map(s,function(e){return e!==i?e:null}):e.map(this.tabs,function(e,t){return t!==i?t:null})),this._setupDisabled(s))},disable:function(i){var s=this.options.disabled;if(s!==!0){if(i===t)s=!0;else{if(i=this._getIndex(i),-1!==e.inArray(i,s))return;s=e.isArray(s)?e.merge([i],s).sort():[i]}this._setupDisabled(s)}},load:function(t,i){t=this._getIndex(t);var a=this,n=this.tabs.eq(t),r=n.find(".ui-tabs-anchor"),o=this._getPanelForTab(n),h={tab:n,panel:o};s(r[0])||(this.xhr=e.ajax(this._ajaxSettings(r,i,h)),this.xhr&&"canceled"!==this.xhr.statusText&&(n.addClass("ui-tabs-loading"),o.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){o.html(e),a._trigger("load",i,h)},1)}).complete(function(e,t){setTimeout(function(){"abort"===t&&a.panels.stop(!1,!0),n.removeClass("ui-tabs-loading"),o.removeAttr("aria-busy"),e===a.xhr&&delete a.xhr},1)})))},_ajaxSettings:function(t,i,s){var a=this;return{url:t.attr("href"),beforeSend:function(t,n){return a._trigger("beforeLoad",i,e.extend({jqXHR:t,ajaxSettings:n},s))}}},_getPanelForTab:function(t){var i=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}})})(jQuery);
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
/*!
* jquery-timepicker v1.4.1 - A jQuery timepicker plugin inspired by Google Calendar. It supports both mouse and keyboard navigation.
* Copyright (c) 2014 Jon Thornton - http://jonthornton.github.com/jquery-timepicker/
* License:
*/
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){function b(a){if(a.minTime&&(a.minTime=s(a.minTime)),a.maxTime&&(a.maxTime=s(a.maxTime)),a.durationTime&&"function"!=typeof a.durationTime&&(a.durationTime=s(a.durationTime)),"now"==a.scrollDefault?a.scrollDefault=s(new Date):a.scrollDefault?a.scrollDefault=s(a.scrollDefault):a.minTime&&(a.scrollDefault=a.minTime),a.scrollDefault&&(a.scrollDefault=s(e(a.scrollDefault,a))),a.timeFormat.match(/[gh]/)&&(a._twelveHourTime=!0),a.disableTimeRanges.length>0){for(var b in a.disableTimeRanges)a.disableTimeRanges[b]=[s(a.disableTimeRanges[b][0]),s(a.disableTimeRanges[b][1])];a.disableTimeRanges=a.disableTimeRanges.sort(function(a,b){return a[0]-b[0]});for(var b=a.disableTimeRanges.length-1;b>0;b--)a.disableTimeRanges[b][0]<=a.disableTimeRanges[b-1][1]&&(a.disableTimeRanges[b-1]=[Math.min(a.disableTimeRanges[b][0],a.disableTimeRanges[b-1][0]),Math.max(a.disableTimeRanges[b][1],a.disableTimeRanges[b-1][1])],a.disableTimeRanges.splice(b,1))}return a}function c(b){var c=b.data("timepicker-settings"),f=b.data("timepicker-list");if(f&&f.length&&(f.remove(),b.data("timepicker-list",!1)),c.useSelect){f=a("<select />",{"class":"ui-timepicker-select"});var g=f}else{f=a("<ul />",{"class":"ui-timepicker-list"});var g=a("<div />",{"class":"ui-timepicker-wrapper",tabindex:-1});g.css({display:"none",position:"absolute"}).append(f)}if(c.noneOption)if(c.noneOption===!0&&(c.noneOption=c.useSelect?"Time...":"None"),a.isArray(c.noneOption)){for(var i in c.noneOption)if(parseInt(i,10)===i){var k=d(c.noneOption[i],c.useSelect);f.append(k)}}else{var k=d(c.noneOption,c.useSelect);f.append(k)}c.className&&g.addClass(c.className),null===c.minTime&&null===c.durationTime||!c.showDuration||(g.addClass("ui-timepicker-with-duration"),g.addClass("ui-timepicker-step-"+c.step));var l=c.minTime;"function"==typeof c.durationTime?l=s(c.durationTime()):null!==c.durationTime&&(l=c.durationTime);var n=null!==c.minTime?c.minTime:0,o=null!==c.maxTime?c.maxTime:n+v-1;n>=o&&(o+=v),o===v-1&&-1!==c.timeFormat.indexOf("H")&&(o=v);for(var t=c.disableTimeRanges,u=0,w=t.length,i=n;o>=i;i+=60*c.step){var x=i,z=r(x,c.timeFormat);if(c.useSelect){var A=a("<option />",{value:z});A.text(z)}else{var A=a("<li />");A.data("time",86400>=x?x:x%86400),A.text(z)}if((null!==c.minTime||null!==c.durationTime)&&c.showDuration){var B=q(i-l,c.step);if(c.useSelect)A.text(A.text()+" ("+B+")");else{var C=a("<span />",{"class":"ui-timepicker-duration"});C.text(" ("+B+")"),A.append(C)}}w>u&&(x>=t[u][1]&&(u+=1),t[u]&&x>=t[u][0]&&x<t[u][1]&&(c.useSelect?A.prop("disabled",!0):A.addClass("ui-timepicker-disabled"))),f.append(A)}if(g.data("timepicker-input",b),b.data("timepicker-list",g),c.useSelect)f.val(e(b.val(),c)),f.on("focus",function(){a(this).data("timepicker-input").trigger("showTimepicker")}),f.on("blur",function(){a(this).data("timepicker-input").trigger("hideTimepicker")}),f.on("change",function(){m(b,a(this).val(),"select")}),b.hide().after(f);else{var D=c.appendTo;"string"==typeof D?D=a(D):"function"==typeof D&&(D=D(b)),D.append(g),j(b,f),f.on("mousedown","li",function(){b.off("focus.timepicker"),b.on("focus.timepicker-ie-hack",function(){b.off("focus.timepicker-ie-hack"),b.on("focus.timepicker",y.show)}),h(b)||b[0].focus(),f.find("li").removeClass("ui-timepicker-selected"),a(this).addClass("ui-timepicker-selected"),p(b)&&(b.trigger("hideTimepicker"),g.hide())})}}function d(b,c){var d,e,f;return"object"==typeof b?(d=b.label,e=b.className,f=b.value):"string"==typeof b?d=b:a.error("Invalid noneOption value"),c?a("<option />",{value:f,"class":e,text:d}):a("<li />",{"class":e,text:d}).data("time",f)}function e(b,c){if(a.isNumeric(b)||(b=s(b)),null===b)return null;var d=60*c.step;return r(Math.round(b/d)*d,c.timeFormat)}function f(){return new Date(1970,1,1,0,0,0)}function g(b){var c=a(b.target),d=c.closest(".ui-timepicker-input");0===d.length&&0===c.closest(".ui-timepicker-wrapper").length&&(y.hide(),a(document).unbind(".ui-timepicker"))}function h(a){var b=a.data("timepicker-settings");return(window.navigator.msMaxTouchPoints||"ontouchstart"in document)&&b.disableTouchKeyboard}function i(b,c,d){if(!d&&0!==d)return!1;var e=b.data("timepicker-settings"),f=!1,g=30*e.step;return c.find("li").each(function(b,c){var e=a(c);if("number"==typeof e.data("time")){var h=e.data("time")-d;return Math.abs(h)<g||h==g?(f=e,!1):void 0}}),f}function j(a,b){b.find("li").removeClass("ui-timepicker-selected");var c=s(l(a),a.data("timepicker-settings"));if(null!==c){var d=i(a,b,c);if(d){var e=d.offset().top-b.offset().top;(e+d.outerHeight()>b.outerHeight()||0>e)&&b.scrollTop(b.scrollTop()+d.position().top-d.outerHeight()),d.addClass("ui-timepicker-selected")}}}function k(b){if(""!==this.value){var c=a(this);if(c.data("timepicker-list"),!c.is(":focus")||b&&"change"==b.type){var d=s(this.value);if(null===d)return c.trigger("timeFormatError"),void 0;var e=c.data("timepicker-settings"),f=!1;if(null!==e.minTime&&d<e.minTime?f=!0:null!==e.maxTime&&d>e.maxTime&&(f=!0),a.each(e.disableTimeRanges,function(){return d>=this[0]&&d<this[1]?(f=!0,!1):void 0}),e.forceRoundTime){var g=d%(60*e.step);g>=30*e.step?d+=60*e.step-g:d-=g}var h=r(d,e.timeFormat);f?m(c,h,"error")&&c.trigger("timeRangeError"):m(c,h)}}}function l(a){return a.is("input")?a.val():a.data("ui-timepicker-value")}function m(a,b,c){if(a.is("input")){a.val(b);var d=a.data("timepicker-settings");d.useSelect&&a.data("timepicker-list").val(e(b,d))}return a.data("ui-timepicker-value")!=b?(a.data("ui-timepicker-value",b),"select"==c?a.trigger("selectTime").trigger("changeTime").trigger("change"):"error"!=c&&a.trigger("changeTime"),!0):(a.trigger("selectTime"),!1)}function n(b){var c=a(this),d=c.data("timepicker-list");if(!d||!d.is(":visible")){if(40!=b.keyCode)return!0;y.show.call(c.get(0)),d=c.data("timepicker-list"),h(c)||c.focus()}switch(b.keyCode){case 13:return p(c)&&y.hide.apply(this),b.preventDefault(),!1;case 38:var e=d.find(".ui-timepicker-selected");return e.length?e.is(":first-child")||(e.removeClass("ui-timepicker-selected"),e.prev().addClass("ui-timepicker-selected"),e.prev().position().top<e.outerHeight()&&d.scrollTop(d.scrollTop()-e.outerHeight())):(d.find("li").each(function(b,c){return a(c).position().top>0?(e=a(c),!1):void 0}),e.addClass("ui-timepicker-selected")),!1;case 40:return e=d.find(".ui-timepicker-selected"),0===e.length?(d.find("li").each(function(b,c){return a(c).position().top>0?(e=a(c),!1):void 0}),e.addClass("ui-timepicker-selected")):e.is(":last-child")||(e.removeClass("ui-timepicker-selected"),e.next().addClass("ui-timepicker-selected"),e.next().position().top+2*e.outerHeight()>d.outerHeight()&&d.scrollTop(d.scrollTop()+e.outerHeight())),!1;case 27:d.find("li").removeClass("ui-timepicker-selected"),y.hide();break;case 9:y.hide();break;default:return!0}}function o(b){var c=a(this),d=c.data("timepicker-list");if(!d||!d.is(":visible"))return!0;if(!c.data("timepicker-settings").typeaheadHighlight)return d.find("li").removeClass("ui-timepicker-selected"),!0;switch(b.keyCode){case 96:case 97:case 98:case 99:case 100:case 101:case 102:case 103:case 104:case 105:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:case 65:case 77:case 80:case 186:case 8:case 46:j(c,d);break;default:return}}function p(a){var b=a.data("timepicker-settings"),c=a.data("timepicker-list"),d=null,e=c.find(".ui-timepicker-selected");if(e.hasClass("ui-timepicker-disabled"))return!1;if(e.length&&(d=e.data("time")),null!==d)if("string"==typeof d)a.val(d);else{var f=r(d,b.timeFormat);m(a,f,"select")}return!0}function q(a,b){var c,d,e=Math.round(a/60),f=[];return 60>e?f=[e,x.mins]:(c=Math.floor(e/60),d=e%60,30==b&&30==d&&(c+=x.decimal+5),f.push(c),f.push(1==c?x.hr:x.hrs),30!=b&&d&&(f.push(d),f.push(x.mins))),f.join(" ")}function r(a,b){if(null!==a){var c=new Date(u.valueOf()+1e3*a);if(!isNaN(c.getTime())){for(var d,e,f="",g=0;g<b.length;g++)switch(e=b.charAt(g)){case"a":f+=c.getHours()>11?x.pm:x.am;break;case"A":f+=c.getHours()>11?x.PM:x.AM;break;case"g":d=c.getHours()%12,f+=0===d?"12":d;break;case"G":f+=c.getHours();break;case"h":d=c.getHours()%12,0!==d&&10>d&&(d="0"+d),f+=0===d?"12":d;break;case"H":d=c.getHours(),a===v&&(d=24),f+=d>9?d:"0"+d;break;case"i":var h=c.getMinutes();f+=h>9?h:"0"+h;break;case"s":a=c.getSeconds(),f+=a>9?a:"0"+a;break;default:f+=e}return f}}}function s(a,b){if(""===a)return null;if(!a||a+0==a)return a;"object"==typeof a&&(a=a.getHours()+":"+t(a.getMinutes())+":"+t(a.getSeconds())),a=a.toLowerCase(),new Date(0);var c;if(-1===a.indexOf(":")?(c=a.match(/^([0-9]):?([0-5][0-9])?:?([0-5][0-9])?\s*([pa]?)m?$/),c||(c=a.match(/^([0-2][0-9]):?([0-5][0-9])?:?([0-5][0-9])?\s*([pa]?)m?$/))):c=a.match(/^(\d{1,2})(?::([0-5][0-9]))?(?::([0-5][0-9]))?\s*([pa]?)m?$/),!c)return null;var d=parseInt(1*c[1],10),e=c[4],f=d;e&&(f=12==d?"p"==c[4]?12:0:d+("p"==c[4]?12:0));var g=1*c[2]||0,h=1*c[3]||0,i=3600*f+60*g+h;if(!e&&b&&b._twelveHourTime&&b.scrollDefault){var j=i-b.scrollDefault;0>j&&j>=v/-2&&(i=(i+v/2)%v)}return i}function t(a){return("0"+a).slice(-2)}var u=f(),v=86400,w={className:null,minTime:null,maxTime:null,durationTime:null,step:30,showDuration:!1,showOnFocus:!0,timeFormat:"g:ia",scrollDefault:null,selectOnBlur:!1,disableTouchKeyboard:!1,forceRoundTime:!1,appendTo:"body",orientation:"ltr",disableTimeRanges:[],closeOnWindowScroll:!1,typeaheadHighlight:!0,noneOption:!1},x={am:"am",pm:"pm",AM:"AM",PM:"PM",decimal:".",mins:"mins",hr:"hr",hrs:"hrs"},y={init:function(d){return this.each(function(){var e=a(this),f=[];for(var g in w)e.data(g)&&(f[g]=e.data(g));var h=a.extend({},w,f,d);h.lang&&(x=a.extend(x,h.lang)),h=b(h),e.data("timepicker-settings",h),e.addClass("ui-timepicker-input"),h.useSelect?c(e):(e.prop("autocomplete","off"),e.on("click.timepicker focus.timepicker",y.show),e.on("change.timepicker",k),e.on("keydown.timepicker",n),e.on("keyup.timepicker",o),k.call(e.get(0)))})},show:function(b){var d=a(this),e=d.data("timepicker-settings");if(b){if(!e.showOnFocus)return!0;b.preventDefault()}if(e.useSelect)return d.data("timepicker-list").focus(),void 0;h(d)&&d.blur();var f=d.data("timepicker-list");if(!d.prop("readonly")&&(f&&0!==f.length&&"function"!=typeof e.durationTime||(c(d),f=d.data("timepicker-list")),!f.is(":visible"))){y.hide(),f.show();var j={};j.left="rtl"==e.orientation?d.offset().left+d.outerWidth()-f.outerWidth()+parseInt(f.css("marginLeft").replace("px",""),10):d.offset().left+parseInt(f.css("marginLeft").replace("px",""),10),j.top=d.offset().top+d.outerHeight(!0)+f.outerHeight()>a(window).height()+a(window).scrollTop()?d.offset().top-f.outerHeight()+parseInt(f.css("marginTop").replace("px",""),10):d.offset().top+d.outerHeight()+parseInt(f.css("marginTop").replace("px",""),10),f.offset(j);var k=f.find(".ui-timepicker-selected");if(k.length||(l(d)?k=i(d,f,s(l(d))):e.scrollDefault&&(k=i(d,f,e.scrollDefault))),k&&k.length){var m=f.scrollTop()+k.position().top-k.outerHeight();f.scrollTop(m)}else f.scrollTop(0);return a(document).on("touchstart.ui-timepicker mousedown.ui-timepicker",g),e.closeOnWindowScroll&&a(document).on("scroll.ui-timepicker",g),d.trigger("showTimepicker"),this}},hide:function(){var b=a(this),c=b.data("timepicker-settings");return c&&c.useSelect&&b.blur(),a(".ui-timepicker-wrapper:visible").each(function(){var b=a(this),c=b.data("timepicker-input"),d=c.data("timepicker-settings");d&&d.selectOnBlur&&p(c),b.hide(),c.trigger("hideTimepicker")}),this},option:function(d,e){var f=this,g=f.data("timepicker-settings"),h=f.data("timepicker-list");if("object"==typeof d)g=a.extend(g,d);else if("string"==typeof d&&"undefined"!=typeof e)g[d]=e;else if("string"==typeof d)return g[d];return g=b(g),f.data("timepicker-settings",g),h&&(h.remove(),f.data("timepicker-list",!1)),g.useSelect&&c(f),this},getSecondsFromMidnight:function(){return s(l(this))},getTime:function(a){var b=this,c=l(b);if(!c)return null;a||(a=new Date);var d=s(c),e=new Date(a);return e.setHours(d/3600),e.setMinutes(d%3600/60),e.setSeconds(d%60),e.setMilliseconds(0),e},setTime:function(a){var b=this,c=r(s(a),b.data("timepicker-settings").timeFormat);return m(b,c),b.data("timepicker-list")&&j(b,b.data("timepicker-list")),this},remove:function(){var a=this;if(a.hasClass("ui-timepicker-input")){var b=a.data("timepicker-settings");return a.removeAttr("autocomplete","off"),a.removeClass("ui-timepicker-input"),a.removeData("timepicker-settings"),a.off(".timepicker"),a.data("timepicker-list")&&a.data("timepicker-list").remove(),b.useSelect&&a.show(),a.removeData("timepicker-list"),this}}};a.fn.timepicker=function(b){return this.length?y[b]?this.hasClass("ui-timepicker-input")?y[b].apply(this,Array.prototype.slice.call(arguments,1)):this:"object"!=typeof b&&b?(a.error("Method "+b+" does not exist on jQuery.timepicker"),void 0):y.init.apply(this,arguments):this}});
\ No newline at end of file
if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof OpenAssessment.Server=="undefined"||!OpenAssessment.Server){OpenAssessment.Server=function(runtime,element){this.runtime=runtime;this.element=element};OpenAssessment.Server.prototype={url:function(handler){return this.runtime.handlerUrl(this.element,handler)},render:function(component){var url=this.url("render_"+component);return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html"}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},renderContinuedPeer:function(){var url=this.url("render_peer_assessment");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{continue_grading:true}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},studentInfo:function(student_id){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_id:student_id}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},submit:function(submission){var url=this.url("submit");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){var success=data[0];if(success){var studentId=data[1];var attemptNum=data[2];defer.resolveWith(this,[studentId,attemptNum])}else{var errorNum=data[1];var errorMsg=data[2];defer.rejectWith(this,[errorNum,errorMsg])}}).fail(function(data){defer.rejectWith(this,["AJAX",gettext("This response could not be submitted.")])})}).promise()},save:function(submission){var url=this.url("save_submission");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This response could not be saved.")])})}).promise()},submitFeedbackOnAssessment:function(text,options){var url=this.url("submit_feedback");var payload=JSON.stringify({feedback_text:text,feedback_options:options});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This feedback could not be submitted.")])})}).promise()},peerAssess:function(optionsSelected,criterionFeedback,overallFeedback){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})}).promise()},selfAssess:function(optionsSelected){var url=this.url("self_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},trainingAssess:function(optionsSelected){var url=this.url("training_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.corrections])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},scheduleTraining:function(){var url=this.url("schedule_training");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},rescheduleUnfinishedTasks:function(){var url=this.url("reschedule_unfinished_tasks");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("One or more rescheduling tasks failed.")])})})},updateEditorContext:function(kwargs){var url=this.url("update_editor_context");var payload=JSON.stringify({prompt:kwargs.prompt,feedback_prompt:kwargs.feedbackPrompt,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This problem could not be saved.")])})}).promise()},checkReleased:function(){var url=this.url("check_released");var payload='""';return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.is_released])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The server could not be contacted.")])})}).promise()},getUploadUrl:function(contentType){var url=this.url("upload_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({contentType:contentType})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve upload url.")])})}).promise()},getDownloadUrl:function(){var url=this.url("download_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve download url.")])})}).promise()}}}if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.BaseView=function(runtime,element,server){this.runtime=runtime;this.element=element;this.server=server;this.responseView=new OpenAssessment.ResponseView(this.element,this.server,this);this.trainingView=new OpenAssessment.StudentTrainingView(this.element,this.server,this);this.selfView=new OpenAssessment.SelfView(this.element,this.server,this);this.peerView=new OpenAssessment.PeerView(this.element,this.server,this);this.gradeView=new OpenAssessment.GradeView(this.element,this.server,this);this.messageView=new OpenAssessment.MessageView(this.element,this.server,this);this.staffInfoView=new OpenAssessment.StaffInfoView(this.element,this.server,this)};OpenAssessment.BaseView.prototype={scrollToTop:function(){if($.scrollTo instanceof Function){$(window).scrollTo($("#openassessment__steps"),800,{offset:-50})}},setUpCollapseExpand:function(parentSel){parentSel.find(".ui-toggle-visibility__control").click(function(eventData){var sel=$(eventData.target).closest(".ui-toggle-visibility");sel.toggleClass("is--collapsed")})},load:function(){this.responseView.load();this.loadAssessmentModules();this.staffInfoView.load()},loadAssessmentModules:function(){this.trainingView.load();this.peerView.load();this.selfView.load();this.gradeView.load()},loadMessageView:function(){this.messageView.load()},toggleActionError:function(type,msg){var element=this.element;var container=null;if(type=="save"){container=".response__submission__actions"}else if(type=="submit"||type=="peer"||type=="self"||type=="student-training"){container=".step__actions"}else if(type=="feedback_assess"){container=".submission__feedback__actions"}else if(type=="upload"){container="#upload__error"}if(container===null){if(msg!==null){console.log(msg)}}else{var msgHtml=msg===null?"":msg;$(container+" .message__content",element).html("<p>"+msgHtml+"</p>");$(container,element).toggleClass("has--error",msg!==null)}},showLoadError:function(step){var container="#openassessment__"+step;$(container).toggleClass("has--error",true);$(container+" .step__status__value i").removeClass().addClass("ico icon-warning-sign");$(container+" .step__status__value .copy").html(gettext("Unable to Load"))}};function OpenAssessmentBlock(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.BaseView(runtime,element,server);view.load()}OpenAssessment.Container=function(containerItem,kwargs){this.containerItem=containerItem;this.containerElement=kwargs.containerElement;this.templateElement=kwargs.templateElement;this.addButtonElement=kwargs.addButtonElement;this.removeButtonClass=kwargs.removeButtonClass;this.containerItemClass=kwargs.containerItemClass;$(this.addButtonElement).click($.proxy(this.add,this));var container=this;$("."+this.removeButtonClass,this.containerElement).click(function(eventData){container.remove(eventData.target)});$("."+this.containerItemClass,this.containerElement).each(function(index,element){new container.containerItem(element)})};OpenAssessment.Container.prototype={add:function(){$(this.templateElement).clone().removeAttr("id").toggleClass("is--hidden",false).toggleClass(this.containerItemClass,true).appendTo($(this.containerElement));var container=this;var containerItem=$("."+this.containerItemClass,this.containerElement).last();containerItem.find("."+this.removeButtonClass).click(function(eventData){container.remove(eventData.target)});new this.containerItem(containerItem.get(0))},remove:function(element){$(element).closest("."+this.containerItemClass).remove()},getItemValues:function(){var values=[];var container=this;$("."+this.containerItemClass,this.containerElement).each(function(index,element){var containerItem=new container.containerItem(element);var fieldValues=containerItem.getFieldValues();values.push(fieldValues)});return values},getItemElement:function(index){var element=$("."+this.containerItemClass,this.containerElement).get(index);return element!==undefined?element:null}};OpenAssessment.RubricOption=function(element){this.element=element};OpenAssessment.RubricOption.prototype={getFieldValues:function(){return{name:OpenAssessment.Fields.stringField($(".openassessment_criterion_option_name",this.element)),points:OpenAssessment.Fields.intField($(".openassessment_criterion_option_points",this.element)),explanation:OpenAssessment.Fields.stringField($(".openassessment_criterion_option_explanation",this.element))}}};OpenAssessment.RubricCriterion=function(element){this.element=element;this.optionContainer=new OpenAssessment.Container(OpenAssessment.RubricOption,{containerElement:$(".openassessment_criterion_option_list",this.element).get(0),templateElement:$("#openassessment_option_template").get(0),addButtonElement:$(".openassessment_criterion_add_option",this.element).get(0),removeButtonClass:"openassessment_criterion_option_remove_button",containerItemClass:"openassessment_criterion_option"})};OpenAssessment.RubricCriterion.prototype={getFieldValues:function(){return{name:OpenAssessment.Fields.stringField($(".openassessment_criterion_name",this.element)),prompt:OpenAssessment.Fields.stringField($(".openassessment_criterion_prompt",this.element)),feedback:OpenAssessment.Fields.stringField($(".openassessment_criterion_feedback",this.element)),options:this.optionContainer.getItemValues()}}};OpenAssessment.GradeView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.GradeView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("grade").done(function(html){$("#openassessment__grade",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){baseView.showLoadError("grade",errMsg)})},installHandlers:function(){var sel=$("#openassessment__grade",this.element);this.baseView.setUpCollapseExpand(sel);var view=this;sel.find("#feedback__submit").click(function(eventObject){eventObject.preventDefault();view.submitFeedbackOnAssessment()})},feedbackText:function(text){if(typeof text==="undefined"){return $("#feedback__remarks__value",this.element).val()}else{$("#feedback__remarks__value",this.element).val(text)}},feedbackOptions:function(options){var view=this;if(typeof options==="undefined"){return $.map($(".feedback__overall__value:checked",view.element),function(element,index){return $(element).val()})}else{$(".feedback__overall__value",this.element).prop("checked",false);$.each(options,function(index,opt){$("#feedback__overall__value--"+opt,view.element).prop("checked",true)})}},setHidden:function(sel,hidden){sel.toggleClass("is--hidden",hidden);sel.attr("aria-hidden",hidden?"true":"false")},isHidden:function(sel){return sel.hasClass("is--hidden")&&sel.attr("aria-hidden")=="true"},feedbackState:function(newState){var containerSel=$(".submission__feedback__content",this.element);var instructionsSel=containerSel.find(".submission__feedback__instructions");var fieldsSel=containerSel.find(".submission__feedback__fields");var actionsSel=containerSel.find(".submission__feedback__actions");var transitionSel=containerSel.find(".transition__status");var messageSel=containerSel.find(".message--complete");if(typeof newState==="undefined"){var isSubmitting=containerSel.hasClass("is--transitioning")&&containerSel.hasClass("is--submitting")&&!this.isHidden(transitionSel)&&this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var hasSubmitted=containerSel.hasClass("is--submitted")&&this.isHidden(transitionSel)&&!this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var isOpen=!containerSel.hasClass("is--submitted")&&!containerSel.hasClass("is--transitioning")&&!containerSel.hasClass("is--submitting")&&this.isHidden(transitionSel)&&this.isHidden(messageSel)&&!this.isHidden(instructionsSel)&&!this.isHidden(fieldsSel)&&!this.isHidden(actionsSel);if(isOpen){return"open"}else if(isSubmitting){return"submitting"}else if(hasSubmitted){return"submitted"}else{throw"Invalid feedback state"}}else{if(newState=="open"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,false);this.setHidden(fieldsSel,false);this.setHidden(actionsSel,false);this.setHidden(transitionSel,true);this.setHidden(messageSel,true)}else if(newState=="submitting"){containerSel.toggleClass("is--transitioning",true);containerSel.toggleClass("is--submitting",true);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,false);this.setHidden(messageSel,true)}else if(newState=="submitted"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",true);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,true);this.setHidden(messageSel,false)}}},submitFeedbackOnAssessment:function(){var view=this;var baseView=this.baseView;$("#feedback__submit",this.element).toggleClass("is--disabled",true);view.feedbackState("submitting");this.server.submitFeedbackOnAssessment(this.feedbackText(),this.feedbackOptions()).done(function(){view.feedbackState("submitted")}).fail(function(errMsg){baseView.toggleActionError("feedback_assess",errMsg)})}};OpenAssessment.MessageView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.MessageView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("message").done(function(html){$("#openassessment__message",view.element).replaceWith(html)}).fail(function(errMsg){baseView.showLoadError("message",errMsg)})}};OpenAssessment.PeerView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.PeerView.prototype={load:function(){var view=this;this.server.render("peer_assessment").done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(false)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")});view.baseView.loadMessageView()},loadContinuedAssessment:function(){var view=this;view.continueAssessmentEnabled(false);this.server.renderContinuedPeer().done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(true)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment");view.continueAssessmentEnabled(true)})},continueAssessmentEnabled:function(enabled){var button=$("#peer-assessment__continue__grading",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},installHandlers:function(isContinuedAssessment){var sel=$("#openassessment__peer-assessment",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#peer-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(view.peerSubmitEnabled,view))}sel.find("#peer-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();if(!isContinuedAssessment){view.peerAssess()}else{view.continuedPeerAssess()}});sel.find("#peer-assessment__continue__grading").click(function(eventObject){eventObject.preventDefault();view.loadContinuedAssessment()})},peerSubmitEnabled:function(enabled){var button=$("#peer-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},peerAssess:function(){var view=this;var baseView=view.baseView;this.peerAssessRequest(function(){view.load();baseView.loadAssessmentModules();baseView.scrollToTop()})},continuedPeerAssess:function(){var view=this;var gradeView=this.baseView.gradeView;var baseView=view.baseView;view.peerAssessRequest(function(){view.loadContinuedAssessment();gradeView.load();baseView.scrollToTop()})},peerAssessRequest:function(successFunction){var view=this;view.baseView.toggleActionError("peer",null);view.peerSubmitEnabled(false);this.server.peerAssess(this.rubric.optionsSelected(),this.rubric.criterionFeedback(),this.overallFeedback()).done(successFunction).fail(function(errMsg){view.baseView.toggleActionError("peer",errMsg);view.peerSubmitEnabled(true)})},overallFeedback:function(overallFeedback){var selector="#assessment__rubric__question--feedback__value";if(typeof overallFeedback==="undefined"){return $(selector,this.element).val()}else{$(selector,this.element).val(overallFeedback)}}};OpenAssessment.ResponseView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.savedResponse="";this.files=null;this.imageType=null;this.lastChangeTime=Date.now();this.errorOnLastSave=false;this.autoSaveTimerId=null};OpenAssessment.ResponseView.prototype={AUTO_SAVE_POLL_INTERVAL:2e3,AUTO_SAVE_WAIT:3e4,MAX_FILE_SIZE:5242880,load:function(){var view=this;this.server.render("submission").done(function(html){$("#openassessment__response",view.element).replaceWith(html);view.installHandlers();view.setAutoSaveEnabled(true)}).fail(function(errMsg){view.baseView.showLoadError("response")})},installHandlers:function(){var sel=$("#openassessment__response",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);this.savedResponse=this.response();var handleChange=function(eventData){view.handleResponseChanged()};sel.find("#submission__answer__value").on("change keyup drop paste",handleChange);var handlePrepareUpload=function(eventData){view.prepareUpload(eventData.target.files)};sel.find("input[type=file]").on("change",handlePrepareUpload);sel.find("#step--response__submit").click(function(eventObject){eventObject.preventDefault();view.submit()});sel.find("#submission__save").click(function(eventObject){eventObject.preventDefault();view.save()});sel.find("#file__upload").click(function(eventObject){eventObject.preventDefault();view.fileUpload()})},setAutoSaveEnabled:function(enabled){if(enabled){if(this.autoSaveTimerId===null){this.autoSaveTimerId=setInterval($.proxy(this.autoSave,this),this.AUTO_SAVE_POLL_INTERVAL)}}else{if(this.autoSaveTimerId!==null){clearInterval(this.autoSaveTimerId)}}},submitEnabled:function(enabled){var sel=$("#step--response__submit",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveEnabled:function(enabled){var sel=$("#submission__save",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveStatus:function(msg){var sel=$("#response__save_status h3",this.element);if(typeof msg==="undefined"){return sel.text()}else{var label=gettext("Status of Your Response");sel.html('<span class="sr">'+label+":"+"</span>\n"+msg)}},unsavedWarningEnabled:function(enabled){if(typeof enabled==="undefined"){return window.onbeforeunload!==null}else{if(enabled){window.onbeforeunload=function(){return gettext("If you leave this page without saving or submitting your response, you'll lose any work you've done on the response.")}}else{window.onbeforeunload=null}}},response:function(text){var sel=$("#submission__answer__value",this.element);if(typeof text==="undefined"){return sel.val()}else{sel.val(text)}},responseChanged:function(){var currentResponse=$.trim(this.response());var savedResponse=$.trim(this.savedResponse);return savedResponse!==currentResponse},autoSave:function(){var timeSinceLastChange=Date.now()-this.lastChangeTime;if(this.responseChanged()&&timeSinceLastChange>this.AUTO_SAVE_WAIT&&!this.errorOnLastSave){this.save()}},handleResponseChanged:function(){var isBlank=$.trim(this.response())!=="";this.submitEnabled(isBlank);if(this.responseChanged()){this.saveEnabled(isBlank);this.saveStatus(gettext("This response has not been saved."));this.unsavedWarningEnabled(true)}this.lastChangeTime=Date.now()},save:function(){this.errorOnLastSave=false;this.saveStatus(gettext("Saving..."));this.baseView.toggleActionError("save",null);this.unsavedWarningEnabled(false);var view=this;var savedResponse=this.response();this.server.save(savedResponse).done(function(){view.savedResponse=savedResponse;var currentResponse=view.response();view.submitEnabled(currentResponse!=="");if(currentResponse==savedResponse){view.saveEnabled(false);view.saveStatus(gettext("This response has been saved but not submitted."))}}).fail(function(errMsg){view.saveStatus(gettext("Error"));view.baseView.toggleActionError("save",errMsg);view.errorOnLastSave=true})},submit:function(){this.submitEnabled(false);var view=this;var baseView=this.baseView;this.confirmSubmission().pipe(function(){var submission=$("#submission__answer__value",view.element).val();baseView.toggleActionError("response",null);return view.server.submit(submission)}).done($.proxy(view.moveToNextStep,view)).fail(function(errCode,errMsg){if(errCode=="ENOMULTI"){view.moveToNextStep()}else{if(errMsg){baseView.toggleActionError("submit",errMsg)}view.submitEnabled(true)}})},moveToNextStep:function(){this.load();this.baseView.loadAssessmentModules();this.unsavedWarningEnabled(false)},confirmSubmission:function(){var msg="You're about to submit your response for this assignment. "+"After you submit this response, you can't change it or submit a new response.";return $.Deferred(function(defer){if(confirm(msg)){defer.resolve()}else{defer.reject()}})},prepareUpload:function(files){this.files=null;this.imageType=files[0].type;if(files[0].size>this.MAX_FILE_SIZE){this.baseView.toggleActionError("upload",gettext("File size must be 5MB or less."))}else if(this.imageType.substring(0,6)!="image/"){this.baseView.toggleActionError("upload",gettext("File must be an image."))}else{this.baseView.toggleActionError("upload",null);this.files=files}$("#file__upload").toggleClass("is--disabled",this.files==null)},fileUpload:function(){var view=this;var fileUpload=$("#file__upload");fileUpload.addClass("is--disabled");this.server.getUploadUrl(view.imageType).done(function(url){var image=view.files[0];$.ajax({url:url,type:"PUT",data:image,async:false,processData:false,contentType:view.imageType,success:function(data,textStatus,jqXHR){view.imageUrl();this.baseView.toggleActionError("upload",null)},error:function(jqXHR,textStatus,errorThrown){view.baseView.toggleActionError("upload",textStatus);fileUpload.removeClass("is--disabled")}})}).fail(function(errMsg){view.baseView.toggleActionError("upload",errMsg);fileUpload.removeClass("is--disabled")})},imageUrl:function(){var view=this;var image=$("#submission__answer__image",view.element);view.server.getDownloadUrl().done(function(url){image.attr("src",url);return url})}};OpenAssessment.Rubric=function(element){this.element=element};OpenAssessment.Rubric.prototype={criterionFeedback:function(criterionFeedback){var selector="textarea.answer__value";var feedback={};$(selector,this.element).each(function(index,sel){if(typeof criterionFeedback!=="undefined"){$(sel).val(criterionFeedback[sel.name]);feedback[sel.name]=criterionFeedback[sel.name]}else{feedback[sel.name]=$(sel).val()}});return feedback},optionsSelected:function(optionsSelected){var selector="input[type=radio]";if(typeof optionsSelected==="undefined"){var options={};$(selector+":checked",this.element).each(function(index,sel){options[sel.name]=sel.value});return options}else{$(selector,this.element).prop("checked",false);$(selector,this.element).each(function(index,sel){if(optionsSelected.hasOwnProperty(sel.name)){if(sel.value==optionsSelected[sel.name]){$(sel).prop("checked",true)}}})}},canSubmitCallback:function(callback){var rubric=this;callback(rubric.canSubmit());$(this.element).on("change keyup drop paste",function(){callback(rubric.canSubmit())})},canSubmit:function(){var numChecked=$("input[type=radio]:checked",this.element).length;var numAvailable=$(".field--radio.assessment__rubric__question.has--options",this.element).length;var completedRequiredComments=true;$("textarea[required]",this.element).each(function(){var trimmedText=$.trim($(this).val());if(trimmedText===""){completedRequiredComments=false}});return numChecked==numAvailable&&completedRequiredComments},showCorrections:function(corrections){var selector="input[type=radio]";var hasErrors=false;$(selector,this.element).each(function(index,sel){var listItem=$(sel).parents(".assessment__rubric__question");if(corrections.hasOwnProperty(sel.name)){hasErrors=true;listItem.find(".message--incorrect").removeClass("is--hidden");listItem.find(".message--correct").addClass("is--hidden")}else{listItem.find(".message--correct").removeClass("is--hidden");listItem.find(".message--incorrect").addClass("is--hidden")}});return hasErrors}};OpenAssessment.SelfView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.SelfView.prototype={load:function(){var view=this;this.server.render("self_assessment").done(function(html){$("#openassessment__self-assessment",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.showLoadError("self-assessment")})},installHandlers:function(){var view=this;var sel=$("#openassessment__self-assessment",view.element);this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#self-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.selfSubmitEnabled,this))}sel.find("#self-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.selfAssess()})},selfSubmitEnabled:function(enabled){var button=$("#self-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},selfAssess:function(){var view=this;var baseView=this.baseView;baseView.toggleActionError("self",null);view.selfSubmitEnabled(false);var options=this.rubric.optionsSelected();this.server.selfAssess(options).done(function(){baseView.loadAssessmentModules();baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("self",errMsg);view.selfSubmitEnabled(true)})}};OpenAssessment.StaffInfoView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.StaffInfoView.prototype={load:function(){var view=this;if($("#openassessment__staff-info",view.element).length>0){this.server.render("staff_info").done(function(html){$("#openassessment__staff-info",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("staff_info")})}},loadStudentInfo:function(){var view=this;var sel=$("#openassessment__staff-info",this.element);var student_id=sel.find("#openassessment__student_id").val();this.server.studentInfo(student_id).done(function(html){$("#openassessment__student-info",view.element).replaceWith(html)}).fail(function(errMsg){view.showLoadError("student_info")})},installHandlers:function(){var sel=$("#openassessment__staff-info",this.element);var view=this;if(sel.length<=0){return}this.baseView.setUpCollapseExpand(sel,function(){});sel.find("#openassessment_student_info_form").submit(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#submit_student_id").click(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#schedule_training").click(function(eventObject){eventObject.preventDefault();view.scheduleTraining()});sel.find("#reschedule_unfinished_tasks").click(function(eventObject){eventObject.preventDefault();view.rescheduleUnfinishedTasks()})},scheduleTraining:function(){var view=this;this.server.scheduleTraining().done(function(msg){$("#schedule_training_message",this.element).text(msg)}).fail(function(errMsg){$("#schedule_training_message",this.element).text(errMsg)})},rescheduleUnfinishedTasks:function(){var view=this;this.server.rescheduleUnfinishedTasks().done(function(msg){$("#reschedule_unfinished_tasks_message",this.element).text(msg)}).fail(function(errMsg){$("#reschedule_unfinished_tasks_message",this.element).text(errMsg)})}};OpenAssessment.StudentTrainingView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.StudentTrainingView.prototype={load:function(){var view=this;this.server.render("student_training").done(function(html){$("#openassessment__student-training",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("student-training")})},installHandlers:function(){var sel=$("#openassessment__student-training",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#student-training--001__assessment",this.element); if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof OpenAssessment.Server=="undefined"||!OpenAssessment.Server){OpenAssessment.Server=function(runtime,element){this.runtime=runtime;this.element=element};OpenAssessment.Server.prototype={url:function(handler){return this.runtime.handlerUrl(this.element,handler)},render:function(component){var url=this.url("render_"+component);return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html"}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},renderContinuedPeer:function(){var url=this.url("render_peer_assessment");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{continue_grading:true}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},studentInfo:function(student_id){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_id:student_id}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},submit:function(submission){var url=this.url("submit");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){var success=data[0];if(success){var studentId=data[1];var attemptNum=data[2];defer.resolveWith(this,[studentId,attemptNum])}else{var errorNum=data[1];var errorMsg=data[2];defer.rejectWith(this,[errorNum,errorMsg])}}).fail(function(data){defer.rejectWith(this,["AJAX",gettext("This response could not be submitted.")])})}).promise()},save:function(submission){var url=this.url("save_submission");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This response could not be saved.")])})}).promise()},submitFeedbackOnAssessment:function(text,options){var url=this.url("submit_feedback");var payload=JSON.stringify({feedback_text:text,feedback_options:options});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This feedback could not be submitted.")])})}).promise()},peerAssess:function(optionsSelected,criterionFeedback,overallFeedback){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})}).promise()},selfAssess:function(optionsSelected){var url=this.url("self_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},trainingAssess:function(optionsSelected){var url=this.url("training_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.corrections])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},scheduleTraining:function(){var url=this.url("schedule_training");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},rescheduleUnfinishedTasks:function(){var url=this.url("reschedule_unfinished_tasks");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("One or more rescheduling tasks failed.")])})})},updateEditorContext:function(kwargs){var url=this.url("update_editor_context");var payload=JSON.stringify({prompt:kwargs.prompt,feedback_prompt:kwargs.feedbackPrompt,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This problem could not be saved.")])})}).promise()},checkReleased:function(){var url=this.url("check_released");var payload='""';return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.is_released])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The server could not be contacted.")])})}).promise()},getUploadUrl:function(contentType){var url=this.url("upload_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({contentType:contentType})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve upload url.")])})}).promise()},getDownloadUrl:function(){var url=this.url("download_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve download url.")])})}).promise()}}}if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.BaseView=function(runtime,element,server){this.runtime=runtime;this.element=element;this.server=server;this.responseView=new OpenAssessment.ResponseView(this.element,this.server,this);this.trainingView=new OpenAssessment.StudentTrainingView(this.element,this.server,this);this.selfView=new OpenAssessment.SelfView(this.element,this.server,this);this.peerView=new OpenAssessment.PeerView(this.element,this.server,this);this.gradeView=new OpenAssessment.GradeView(this.element,this.server,this);this.messageView=new OpenAssessment.MessageView(this.element,this.server,this);this.staffInfoView=new OpenAssessment.StaffInfoView(this.element,this.server,this)};OpenAssessment.BaseView.prototype={scrollToTop:function(){if($.scrollTo instanceof Function){$(window).scrollTo($("#openassessment__steps"),800,{offset:-50})}},setUpCollapseExpand:function(parentSel){parentSel.find(".ui-toggle-visibility__control").click(function(eventData){var sel=$(eventData.target).closest(".ui-toggle-visibility");sel.toggleClass("is--collapsed")})},load:function(){this.responseView.load();this.loadAssessmentModules();this.staffInfoView.load()},loadAssessmentModules:function(){this.trainingView.load();this.peerView.load();this.selfView.load();this.gradeView.load()},loadMessageView:function(){this.messageView.load()},toggleActionError:function(type,msg){var element=this.element;var container=null;if(type=="save"){container=".response__submission__actions"}else if(type=="submit"||type=="peer"||type=="self"||type=="student-training"){container=".step__actions"}else if(type=="feedback_assess"){container=".submission__feedback__actions"}else if(type=="upload"){container="#upload__error"}if(container===null){if(msg!==null){console.log(msg)}}else{var msgHtml=msg===null?"":msg;$(container+" .message__content",element).html("<p>"+msgHtml+"</p>");$(container,element).toggleClass("has--error",msg!==null)}},showLoadError:function(step){var container="#openassessment__"+step;$(container).toggleClass("has--error",true);$(container+" .step__status__value i").removeClass().addClass("ico icon-warning-sign");$(container+" .step__status__value .copy").html(gettext("Unable to Load"))}};function OpenAssessmentBlock(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.BaseView(runtime,element,server);view.load()}OpenAssessment.Container=function(containerItem,kwargs){this.containerItem=containerItem;this.containerElement=kwargs.containerElement;this.templateElement=kwargs.templateElement;this.addButtonElement=kwargs.addButtonElement;this.removeButtonClass=kwargs.removeButtonClass;this.containerItemClass=kwargs.containerItemClass;$(this.addButtonElement).click($.proxy(this.add,this));var container=this;$("."+this.removeButtonClass,this.containerElement).click(function(eventData){container.remove(eventData.target)});$("."+this.containerItemClass,this.containerElement).each(function(index,element){new container.containerItem(element)})};OpenAssessment.Container.prototype={add:function(){$(this.templateElement).children().first().clone().removeAttr("id").toggleClass("is--hidden",false).toggleClass(this.containerItemClass,true).appendTo($(this.containerElement));var container=this;var containerItem=$("."+this.containerItemClass,this.containerElement).last();containerItem.find("."+this.removeButtonClass).click(function(eventData){container.remove(eventData.target)});new this.containerItem(containerItem.get(0))},remove:function(element){$(element).closest("."+this.containerItemClass).remove()},getItemValues:function(){var values=[];var container=this;$("."+this.containerItemClass,this.containerElement).each(function(index,element){var containerItem=new container.containerItem(element);var fieldValues=containerItem.getFieldValues();values.push(fieldValues)});return values},getItemElement:function(index){var element=$("."+this.containerItemClass,this.containerElement).get(index);return element!==undefined?element:null}};OpenAssessment.RubricOption=function(element){this.element=element};OpenAssessment.RubricOption.prototype={getFieldValues:function(){return{name:OpenAssessment.Fields.stringField($(".openassessment_criterion_option_name",this.element)),points:OpenAssessment.Fields.intField($(".openassessment_criterion_option_points",this.element)),explanation:OpenAssessment.Fields.stringField($(".openassessment_criterion_option_explanation",this.element))}}};OpenAssessment.RubricCriterion=function(element){this.element=element;this.optionContainer=new OpenAssessment.Container(OpenAssessment.RubricOption,{containerElement:$(".openassessment_criterion_option_list",this.element).get(0),templateElement:$("#openassessment_option_template").get(0),addButtonElement:$(".openassessment_criterion_add_option",this.element).get(0),removeButtonClass:"openassessment_criterion_option_remove_button",containerItemClass:"openassessment_criterion_option"})};OpenAssessment.RubricCriterion.prototype={getFieldValues:function(){return{name:OpenAssessment.Fields.stringField($(".openassessment_criterion_name",this.element)),prompt:OpenAssessment.Fields.stringField($(".openassessment_criterion_prompt",this.element)),feedback:OpenAssessment.Fields.stringField($(".openassessment_criterion_feedback",this.element)),options:this.optionContainer.getItemValues()}}};OpenAssessment.GradeView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.GradeView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("grade").done(function(html){$("#openassessment__grade",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){baseView.showLoadError("grade",errMsg)})},installHandlers:function(){var sel=$("#openassessment__grade",this.element);this.baseView.setUpCollapseExpand(sel);var view=this;sel.find("#feedback__submit").click(function(eventObject){eventObject.preventDefault();view.submitFeedbackOnAssessment()})},feedbackText:function(text){if(typeof text==="undefined"){return $("#feedback__remarks__value",this.element).val()}else{$("#feedback__remarks__value",this.element).val(text)}},feedbackOptions:function(options){var view=this;if(typeof options==="undefined"){return $.map($(".feedback__overall__value:checked",view.element),function(element,index){return $(element).val()})}else{$(".feedback__overall__value",this.element).prop("checked",false);$.each(options,function(index,opt){$("#feedback__overall__value--"+opt,view.element).prop("checked",true)})}},setHidden:function(sel,hidden){sel.toggleClass("is--hidden",hidden);sel.attr("aria-hidden",hidden?"true":"false")},isHidden:function(sel){return sel.hasClass("is--hidden")&&sel.attr("aria-hidden")=="true"},feedbackState:function(newState){var containerSel=$(".submission__feedback__content",this.element);var instructionsSel=containerSel.find(".submission__feedback__instructions");var fieldsSel=containerSel.find(".submission__feedback__fields");var actionsSel=containerSel.find(".submission__feedback__actions");var transitionSel=containerSel.find(".transition__status");var messageSel=containerSel.find(".message--complete");if(typeof newState==="undefined"){var isSubmitting=containerSel.hasClass("is--transitioning")&&containerSel.hasClass("is--submitting")&&!this.isHidden(transitionSel)&&this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var hasSubmitted=containerSel.hasClass("is--submitted")&&this.isHidden(transitionSel)&&!this.isHidden(messageSel)&&this.isHidden(instructionsSel)&&this.isHidden(fieldsSel)&&this.isHidden(actionsSel);var isOpen=!containerSel.hasClass("is--submitted")&&!containerSel.hasClass("is--transitioning")&&!containerSel.hasClass("is--submitting")&&this.isHidden(transitionSel)&&this.isHidden(messageSel)&&!this.isHidden(instructionsSel)&&!this.isHidden(fieldsSel)&&!this.isHidden(actionsSel);if(isOpen){return"open"}else if(isSubmitting){return"submitting"}else if(hasSubmitted){return"submitted"}else{throw"Invalid feedback state"}}else{if(newState=="open"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,false);this.setHidden(fieldsSel,false);this.setHidden(actionsSel,false);this.setHidden(transitionSel,true);this.setHidden(messageSel,true)}else if(newState=="submitting"){containerSel.toggleClass("is--transitioning",true);containerSel.toggleClass("is--submitting",true);containerSel.toggleClass("is--submitted",false);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,false);this.setHidden(messageSel,true)}else if(newState=="submitted"){containerSel.toggleClass("is--transitioning",false);containerSel.toggleClass("is--submitting",false);containerSel.toggleClass("is--submitted",true);this.setHidden(instructionsSel,true);this.setHidden(fieldsSel,true);this.setHidden(actionsSel,true);this.setHidden(transitionSel,true);this.setHidden(messageSel,false)}}},submitFeedbackOnAssessment:function(){var view=this;var baseView=this.baseView;$("#feedback__submit",this.element).toggleClass("is--disabled",true);view.feedbackState("submitting");this.server.submitFeedbackOnAssessment(this.feedbackText(),this.feedbackOptions()).done(function(){view.feedbackState("submitted")}).fail(function(errMsg){baseView.toggleActionError("feedback_assess",errMsg)})}};OpenAssessment.MessageView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.MessageView.prototype={load:function(){var view=this;var baseView=this.baseView;this.server.render("message").done(function(html){$("#openassessment__message",view.element).replaceWith(html)}).fail(function(errMsg){baseView.showLoadError("message",errMsg)})}};OpenAssessment.PeerView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.PeerView.prototype={load:function(){var view=this;this.server.render("peer_assessment").done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(false)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment")});view.baseView.loadMessageView()},loadContinuedAssessment:function(){var view=this;view.continueAssessmentEnabled(false);this.server.renderContinuedPeer().done(function(html){$("#openassessment__peer-assessment",view.element).replaceWith(html);view.installHandlers(true)}).fail(function(errMsg){view.baseView.showLoadError("peer-assessment");view.continueAssessmentEnabled(true)})},continueAssessmentEnabled:function(enabled){var button=$("#peer-assessment__continue__grading",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},installHandlers:function(isContinuedAssessment){var sel=$("#openassessment__peer-assessment",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#peer-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(view.peerSubmitEnabled,view))}sel.find("#peer-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();if(!isContinuedAssessment){view.peerAssess()}else{view.continuedPeerAssess()}});sel.find("#peer-assessment__continue__grading").click(function(eventObject){eventObject.preventDefault();view.loadContinuedAssessment()})},peerSubmitEnabled:function(enabled){var button=$("#peer-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},peerAssess:function(){var view=this;var baseView=view.baseView;this.peerAssessRequest(function(){view.load();baseView.loadAssessmentModules();baseView.scrollToTop()})},continuedPeerAssess:function(){var view=this;var gradeView=this.baseView.gradeView;var baseView=view.baseView;view.peerAssessRequest(function(){view.loadContinuedAssessment();gradeView.load();baseView.scrollToTop()})},peerAssessRequest:function(successFunction){var view=this;view.baseView.toggleActionError("peer",null);view.peerSubmitEnabled(false);this.server.peerAssess(this.rubric.optionsSelected(),this.rubric.criterionFeedback(),this.overallFeedback()).done(successFunction).fail(function(errMsg){view.baseView.toggleActionError("peer",errMsg);view.peerSubmitEnabled(true)})},overallFeedback:function(overallFeedback){var selector="#assessment__rubric__question--feedback__value";if(typeof overallFeedback==="undefined"){return $(selector,this.element).val()}else{$(selector,this.element).val(overallFeedback)}}};OpenAssessment.ResponseView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.savedResponse="";this.files=null;this.imageType=null;this.lastChangeTime=Date.now();this.errorOnLastSave=false;this.autoSaveTimerId=null};OpenAssessment.ResponseView.prototype={AUTO_SAVE_POLL_INTERVAL:2e3,AUTO_SAVE_WAIT:3e4,MAX_FILE_SIZE:5242880,load:function(){var view=this;this.server.render("submission").done(function(html){$("#openassessment__response",view.element).replaceWith(html);view.installHandlers();view.setAutoSaveEnabled(true)}).fail(function(errMsg){view.baseView.showLoadError("response")})},installHandlers:function(){var sel=$("#openassessment__response",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);this.savedResponse=this.response();var handleChange=function(eventData){view.handleResponseChanged()};sel.find("#submission__answer__value").on("change keyup drop paste",handleChange);var handlePrepareUpload=function(eventData){view.prepareUpload(eventData.target.files)};sel.find("input[type=file]").on("change",handlePrepareUpload);sel.find("#step--response__submit").click(function(eventObject){eventObject.preventDefault();view.submit()});sel.find("#submission__save").click(function(eventObject){eventObject.preventDefault();view.save()});sel.find("#file__upload").click(function(eventObject){eventObject.preventDefault();view.fileUpload()})},setAutoSaveEnabled:function(enabled){if(enabled){if(this.autoSaveTimerId===null){this.autoSaveTimerId=setInterval($.proxy(this.autoSave,this),this.AUTO_SAVE_POLL_INTERVAL)}}else{if(this.autoSaveTimerId!==null){clearInterval(this.autoSaveTimerId)}}},submitEnabled:function(enabled){var sel=$("#step--response__submit",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveEnabled:function(enabled){var sel=$("#submission__save",this.element);if(typeof enabled==="undefined"){return!sel.hasClass("is--disabled")}else{sel.toggleClass("is--disabled",!enabled)}},saveStatus:function(msg){var sel=$("#response__save_status h3",this.element);if(typeof msg==="undefined"){return sel.text()}else{var label=gettext("Status of Your Response");sel.html('<span class="sr">'+label+":"+"</span>\n"+msg)}},unsavedWarningEnabled:function(enabled){if(typeof enabled==="undefined"){return window.onbeforeunload!==null}else{if(enabled){window.onbeforeunload=function(){return gettext("If you leave this page without saving or submitting your response, you'll lose any work you've done on the response.")}}else{window.onbeforeunload=null}}},response:function(text){var sel=$("#submission__answer__value",this.element);if(typeof text==="undefined"){return sel.val()}else{sel.val(text)}},responseChanged:function(){var currentResponse=$.trim(this.response());var savedResponse=$.trim(this.savedResponse);return savedResponse!==currentResponse},autoSave:function(){var timeSinceLastChange=Date.now()-this.lastChangeTime;if(this.responseChanged()&&timeSinceLastChange>this.AUTO_SAVE_WAIT&&!this.errorOnLastSave){this.save()}},handleResponseChanged:function(){var isBlank=$.trim(this.response())!=="";this.submitEnabled(isBlank);if(this.responseChanged()){this.saveEnabled(isBlank);this.saveStatus(gettext("This response has not been saved."));this.unsavedWarningEnabled(true)}this.lastChangeTime=Date.now()},save:function(){this.errorOnLastSave=false;this.saveStatus(gettext("Saving..."));this.baseView.toggleActionError("save",null);this.unsavedWarningEnabled(false);var view=this;var savedResponse=this.response();this.server.save(savedResponse).done(function(){view.savedResponse=savedResponse;var currentResponse=view.response();view.submitEnabled(currentResponse!=="");if(currentResponse==savedResponse){view.saveEnabled(false);view.saveStatus(gettext("This response has been saved but not submitted."))}}).fail(function(errMsg){view.saveStatus(gettext("Error"));view.baseView.toggleActionError("save",errMsg);view.errorOnLastSave=true})},submit:function(){this.submitEnabled(false);var view=this;var baseView=this.baseView;this.confirmSubmission().pipe(function(){var submission=$("#submission__answer__value",view.element).val();baseView.toggleActionError("response",null);return view.server.submit(submission)}).done($.proxy(view.moveToNextStep,view)).fail(function(errCode,errMsg){if(errCode=="ENOMULTI"){view.moveToNextStep()}else{if(errMsg){baseView.toggleActionError("submit",errMsg)}view.submitEnabled(true)}})},moveToNextStep:function(){this.load();this.baseView.loadAssessmentModules();this.unsavedWarningEnabled(false)},confirmSubmission:function(){var msg="You're about to submit your response for this assignment. "+"After you submit this response, you can't change it or submit a new response.";return $.Deferred(function(defer){if(confirm(msg)){defer.resolve()}else{defer.reject()}})},prepareUpload:function(files){this.files=null;this.imageType=files[0].type;if(files[0].size>this.MAX_FILE_SIZE){this.baseView.toggleActionError("upload",gettext("File size must be 5MB or less."))}else if(this.imageType.substring(0,6)!="image/"){this.baseView.toggleActionError("upload",gettext("File must be an image."))}else{this.baseView.toggleActionError("upload",null);this.files=files}$("#file__upload").toggleClass("is--disabled",this.files==null)},fileUpload:function(){var view=this;var fileUpload=$("#file__upload");fileUpload.addClass("is--disabled");this.server.getUploadUrl(view.imageType).done(function(url){var image=view.files[0];$.ajax({url:url,type:"PUT",data:image,async:false,processData:false,contentType:view.imageType,success:function(data,textStatus,jqXHR){view.imageUrl();this.baseView.toggleActionError("upload",null)},error:function(jqXHR,textStatus,errorThrown){view.baseView.toggleActionError("upload",textStatus);fileUpload.removeClass("is--disabled")}})}).fail(function(errMsg){view.baseView.toggleActionError("upload",errMsg);fileUpload.removeClass("is--disabled")})},imageUrl:function(){var view=this;var image=$("#submission__answer__image",view.element);view.server.getDownloadUrl().done(function(url){image.attr("src",url);return url})}};OpenAssessment.Rubric=function(element){this.element=element};OpenAssessment.Rubric.prototype={criterionFeedback:function(criterionFeedback){var selector="textarea.answer__value";var feedback={};$(selector,this.element).each(function(index,sel){if(typeof criterionFeedback!=="undefined"){$(sel).val(criterionFeedback[sel.name]);feedback[sel.name]=criterionFeedback[sel.name]}else{feedback[sel.name]=$(sel).val()}});return feedback},optionsSelected:function(optionsSelected){var selector="input[type=radio]";if(typeof optionsSelected==="undefined"){var options={};$(selector+":checked",this.element).each(function(index,sel){options[sel.name]=sel.value});return options}else{$(selector,this.element).prop("checked",false);$(selector,this.element).each(function(index,sel){if(optionsSelected.hasOwnProperty(sel.name)){if(sel.value==optionsSelected[sel.name]){$(sel).prop("checked",true)}}})}},canSubmitCallback:function(callback){var rubric=this;callback(rubric.canSubmit());$(this.element).on("change keyup drop paste",function(){callback(rubric.canSubmit())})},canSubmit:function(){var numChecked=$("input[type=radio]:checked",this.element).length;var numAvailable=$(".field--radio.assessment__rubric__question.has--options",this.element).length;var completedRequiredComments=true;$("textarea[required]",this.element).each(function(){var trimmedText=$.trim($(this).val());if(trimmedText===""){completedRequiredComments=false}});return numChecked==numAvailable&&completedRequiredComments},showCorrections:function(corrections){var selector="input[type=radio]";var hasErrors=false;$(selector,this.element).each(function(index,sel){var listItem=$(sel).parents(".assessment__rubric__question");if(corrections.hasOwnProperty(sel.name)){hasErrors=true;listItem.find(".message--incorrect").removeClass("is--hidden");listItem.find(".message--correct").addClass("is--hidden")}else{listItem.find(".message--correct").removeClass("is--hidden");listItem.find(".message--incorrect").addClass("is--hidden")}});return hasErrors}};OpenAssessment.SelfView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.SelfView.prototype={load:function(){var view=this;this.server.render("self_assessment").done(function(html){$("#openassessment__self-assessment",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.showLoadError("self-assessment")})},installHandlers:function(){var view=this;var sel=$("#openassessment__self-assessment",view.element);this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#self-assessment--001__assessment",this.element);if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.selfSubmitEnabled,this))}sel.find("#self-assessment--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.selfAssess()})},selfSubmitEnabled:function(enabled){var button=$("#self-assessment--001__assessment__submit",this.element);if(typeof enabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!enabled)}},selfAssess:function(){var view=this;var baseView=this.baseView;baseView.toggleActionError("self",null);view.selfSubmitEnabled(false);var options=this.rubric.optionsSelected();this.server.selfAssess(options).done(function(){baseView.loadAssessmentModules();baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("self",errMsg);view.selfSubmitEnabled(true)})}};OpenAssessment.StaffInfoView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView};OpenAssessment.StaffInfoView.prototype={load:function(){var view=this;if($("#openassessment__staff-info",view.element).length>0){this.server.render("staff_info").done(function(html){$("#openassessment__staff-info",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("staff_info")})}},loadStudentInfo:function(){var view=this;var sel=$("#openassessment__staff-info",this.element);var student_id=sel.find("#openassessment__student_id").val();this.server.studentInfo(student_id).done(function(html){$("#openassessment__student-info",view.element).replaceWith(html)}).fail(function(errMsg){view.showLoadError("student_info")})},installHandlers:function(){var sel=$("#openassessment__staff-info",this.element);var view=this;if(sel.length<=0){return}this.baseView.setUpCollapseExpand(sel,function(){});sel.find("#openassessment_student_info_form").submit(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#submit_student_id").click(function(eventObject){eventObject.preventDefault();view.loadStudentInfo()});sel.find("#schedule_training").click(function(eventObject){eventObject.preventDefault();view.scheduleTraining()});sel.find("#reschedule_unfinished_tasks").click(function(eventObject){eventObject.preventDefault();view.rescheduleUnfinishedTasks()})},scheduleTraining:function(){var view=this;this.server.scheduleTraining().done(function(msg){$("#schedule_training_message",this.element).text(msg)}).fail(function(errMsg){$("#schedule_training_message",this.element).text(errMsg)})},rescheduleUnfinishedTasks:function(){var view=this;this.server.rescheduleUnfinishedTasks().done(function(msg){$("#reschedule_unfinished_tasks_message",this.element).text(msg)}).fail(function(errMsg){$("#reschedule_unfinished_tasks_message",this.element).text(errMsg)})}};OpenAssessment.StudentTrainingView=function(element,server,baseView){this.element=element;this.server=server;this.baseView=baseView;this.rubric=null};OpenAssessment.StudentTrainingView.prototype={load:function(){var view=this;this.server.render("student_training").done(function(html){$("#openassessment__student-training",view.element).replaceWith(html);view.installHandlers()}).fail(function(errMsg){view.baseView.showLoadError("student-training")})},installHandlers:function(){var sel=$("#openassessment__student-training",this.element);var view=this;this.baseView.setUpCollapseExpand(sel);var rubricSelector=$("#student-training--001__assessment",this.element);
if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.assessButtonEnabled,this))}sel.find("#student-training--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.assess()})},assess:function(){this.assessButtonEnabled(false);var options={};if(this.rubric!==null){options=this.rubric.optionsSelected()}var view=this;var baseView=this.baseView;this.server.trainingAssess(options).done(function(corrections){var incorrect=$("#openassessment__student-training--incorrect",this.element);var instructions=$("#openassessment__student-training--instructions",this.element);if(!view.rubric.showCorrections(corrections)){view.load();baseView.loadAssessmentModules();incorrect.addClass("is--hidden");instructions.removeClass("is--hidden")}else{instructions.addClass("is--hidden");incorrect.removeClass("is--hidden")}baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("student-training",errMsg);view.assessButtonEnabled(true)})},assessButtonEnabled:function(isEnabled){var button=$("#student-training--001__assessment__submit",this.element);if(typeof isEnabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!isEnabled)}}}; if(rubricSelector.size()>0){var rubricElement=rubricSelector.get(0);this.rubric=new OpenAssessment.Rubric(rubricElement)}if(this.rubric!==null){this.rubric.canSubmitCallback($.proxy(this.assessButtonEnabled,this))}sel.find("#student-training--001__assessment__submit").click(function(eventObject){eventObject.preventDefault();view.assess()})},assess:function(){this.assessButtonEnabled(false);var options={};if(this.rubric!==null){options=this.rubric.optionsSelected()}var view=this;var baseView=this.baseView;this.server.trainingAssess(options).done(function(corrections){var incorrect=$("#openassessment__student-training--incorrect",this.element);var instructions=$("#openassessment__student-training--instructions",this.element);if(!view.rubric.showCorrections(corrections)){view.load();baseView.loadAssessmentModules();incorrect.addClass("is--hidden");instructions.removeClass("is--hidden")}else{instructions.addClass("is--hidden");incorrect.removeClass("is--hidden")}baseView.scrollToTop()}).fail(function(errMsg){baseView.toggleActionError("student-training",errMsg);view.assessButtonEnabled(true)})},assessButtonEnabled:function(isEnabled){var button=$("#student-training--001__assessment__submit",this.element);if(typeof isEnabled==="undefined"){return!button.hasClass("is--disabled")}else{button.toggleClass("is--disabled",!isEnabled)}}};
\ No newline at end of file
if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof OpenAssessment.Server=="undefined"||!OpenAssessment.Server){OpenAssessment.Server=function(runtime,element){this.runtime=runtime;this.element=element};OpenAssessment.Server.prototype={url:function(handler){return this.runtime.handlerUrl(this.element,handler)},render:function(component){var url=this.url("render_"+component);return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html"}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},renderContinuedPeer:function(){var url=this.url("render_peer_assessment");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{continue_grading:true}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},studentInfo:function(student_id){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_id:student_id}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},submit:function(submission){var url=this.url("submit");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){var success=data[0];if(success){var studentId=data[1];var attemptNum=data[2];defer.resolveWith(this,[studentId,attemptNum])}else{var errorNum=data[1];var errorMsg=data[2];defer.rejectWith(this,[errorNum,errorMsg])}}).fail(function(data){defer.rejectWith(this,["AJAX",gettext("This response could not be submitted.")])})}).promise()},save:function(submission){var url=this.url("save_submission");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This response could not be saved.")])})}).promise()},submitFeedbackOnAssessment:function(text,options){var url=this.url("submit_feedback");var payload=JSON.stringify({feedback_text:text,feedback_options:options});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This feedback could not be submitted.")])})}).promise()},peerAssess:function(optionsSelected,criterionFeedback,overallFeedback){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})}).promise()},selfAssess:function(optionsSelected){var url=this.url("self_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},trainingAssess:function(optionsSelected){var url=this.url("training_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.corrections])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},scheduleTraining:function(){var url=this.url("schedule_training");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},rescheduleUnfinishedTasks:function(){var url=this.url("reschedule_unfinished_tasks");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("One or more rescheduling tasks failed.")])})})},updateEditorContext:function(kwargs){var url=this.url("update_editor_context");var payload=JSON.stringify({prompt:kwargs.prompt,feedback_prompt:kwargs.feedbackPrompt,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This problem could not be saved.")])})}).promise()},checkReleased:function(){var url=this.url("check_released");var payload='""';return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.is_released])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The server could not be contacted.")])})}).promise()},getUploadUrl:function(contentType){var url=this.url("upload_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({contentType:contentType})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve upload url.")])})}).promise()},getDownloadUrl:function(){var url=this.url("download_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve download url.")])})}).promise()}}}if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.StudioView=function(runtime,element,server){this.element=element;this.runtime=runtime;this.server=server;this.fixModalHeight();$(".openassessment_editor_content_and_tabs",this.element).tabs();this.promptView=new OpenAssessment.EditPromptView($("#oa_prompt_editor_wrapper",this.element).get(0));var studentTrainingView=new OpenAssessment.EditStudentTrainingView($("#oa_student_training_editor",this.element).get(0));var peerAssessmentView=new OpenAssessment.EditPeerAssessmentView($("#oa_peer_assessment_editor",this.element).get(0));var selfAssessmentView=new OpenAssessment.EditSelfAssessmentView($("#oa_self_assessment_editor",this.element).get(0));var exampleBasedAssessmentView=new OpenAssessment.EditExampleBasedAssessmentView($("#oa_ai_assessment_editor",this.element).get(0));var assessmentLookupDictionary={};assessmentLookupDictionary[studentTrainingView.getID()]=studentTrainingView;assessmentLookupDictionary[peerAssessmentView.getID()]=peerAssessmentView;assessmentLookupDictionary[selfAssessmentView.getID()]=selfAssessmentView;assessmentLookupDictionary[exampleBasedAssessmentView.getID()]=exampleBasedAssessmentView;this.settingsView=new OpenAssessment.EditSettingsView($("#oa_basic_settings_editor",this.element).get(0),assessmentLookupDictionary);this.rubricView=new OpenAssessment.EditRubricView($("#oa_rubric_editor_wrapper",this.element).get(0));$(".openassessment_save_button",this.element).click($.proxy(this.save,this));$(".openassessment_cancel_button",this.element).click($.proxy(this.cancel,this));this.initializeSortableAssessments()};OpenAssessment.StudioView.prototype={fixModalHeight:function(){$(this.element).addClass("openassessment_full_height").parentsUntil(".modal-window").addClass("openassessment_full_height");$(this.element).closest(".modal-window").addClass("openassessment_modal_window")},initializeSortableAssessments:function(){var view=this;$("#openassessment_assessment_module_settings_editors",view.element).sortable({start:function(event,ui){$(".openassessment_assessment_module_editor",view.element).hide();var targetHeight="auto";ui.placeholder.height(targetHeight);ui.helper.height(targetHeight);$("#openassessment_assessment_module_settings_editors",view.element).sortable("refresh").sortable("refreshPositions")},stop:function(event,ui){$(".openassessment_assessment_module_editor",view.element).show()},snap:true,axis:"y",handle:".drag-handle",cursorAt:{top:20}});$("#openassessment_assessment_module_settings_editors",view.element).disableSelection()},save:function(){var view=this;this.server.checkReleased().done(function(isReleased){if(isReleased){view.confirmPostReleaseUpdate($.proxy(view.updateEditorContext,view))}else{view.updateEditorContext()}}).fail(function(errMsg){view.showError(errMsg)})},confirmPostReleaseUpdate:function(onConfirm){var msg=gettext("This problem has already been released. Any changes will apply only to future assessments.");if(confirm(msg)){onConfirm()}},updateEditorContext:function(){this.runtime.notify("save",{state:"start"});var view=this;this.server.updateEditorContext({prompt:view.promptView.promptText(),feedbackPrompt:view.rubricView.feedbackPrompt(),criteria:view.rubricView.criteriaDefinition(),title:view.settingsView.displayName(),submissionStart:view.settingsView.submissionStart(),submissionDue:view.settingsView.submissionDue(),assessments:view.settingsView.assessmentsDescription()}).done(function(){view.runtime.notify("save",{state:"end"})}).fail(function(msg){view.showError(msg)})},cancel:function(){this.runtime.notify("cancel",{})},showError:function(errorMsg){this.runtime.notify("error",{msg:errorMsg})}};function OpenAssessmentEditor(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.StudioView(runtime,element,server)}OpenAssessment.ToggleControl=function(element,hiddenSelector,shownSelector){this.element=element;this.hiddenSelector=hiddenSelector;this.shownSelector=shownSelector};OpenAssessment.ToggleControl.prototype={install:function(checkboxSelector){$(checkboxSelector,this.element).change(this,function(event){var control=event.data;if(this.checked){control.show()}else{control.hide()}});return this},show:function(){$(this.hiddenSelector,this.element).addClass("is--hidden");$(this.shownSelector,this.element).removeClass("is--hidden")},hide:function(){$(this.hiddenSelector,this.element).removeClass("is--hidden");$(this.shownSelector,this.element).addClass("is--hidden")}};OpenAssessment.EditPeerAssessmentView=function(element){this.element=element;this.name="peer-assessment";new OpenAssessment.ToggleControl(this.element,"#peer_assessment_description_closed","#peer_assessment_settings_editor").install("#include_peer_assessment")};OpenAssessment.EditPeerAssessmentView.prototype={description:function(){return{must_grade:this.mustGradeNum(),must_be_graded_by:this.mustBeGradedByNum(),start:this.startDatetime(),due:this.dueDatetime()}},isEnabled:function(isEnabled){var sel=$("#include_peer_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},mustGradeNum:function(num){var sel=$("#peer_assessment_must_grade",this.element);return OpenAssessment.Fields.intField(sel,num)},mustBeGradedByNum:function(num){var sel=$("#peer_assessment_graded_by",this.element);return OpenAssessment.Fields.intField(sel,num)},startDatetime:function(datetime){var sel=$("#peer_assessment_start_date",this.element);return OpenAssessment.Fields.datetimeField(sel,datetime)},dueDatetime:function(datetime){var sel=$("#peer_assessment_due_date",this.element);return OpenAssessment.Fields.datetimeField(sel,datetime)},getID:function(){return $(this.element).attr("id")}};OpenAssessment.EditSelfAssessmentView=function(element){this.element=element;this.name="self-assessment";new OpenAssessment.ToggleControl(this.element,"#self_assessment_description_closed","#self_assessment_settings_editor").install("#include_self_assessment")};OpenAssessment.EditSelfAssessmentView.prototype={description:function(){return{start:this.startDatetime(),due:this.dueDatetime()}},isEnabled:function(isEnabled){var sel=$("#include_self_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},startDatetime:function(datetime){var sel=$("#self_assessment_start_date",this.element);return OpenAssessment.Fields.datetimeField(sel,datetime)},dueDatetime:function(datetime){var sel=$("#self_assessment_due_date",this.element);return OpenAssessment.Fields.datetimeField(sel,datetime)},getID:function(){return $(this.element).attr("id")}};OpenAssessment.EditStudentTrainingView=function(element){this.element=element;this.name="student-training";new OpenAssessment.ToggleControl(this.element,"#student_training_description_closed","#student_training_settings_editor").install("#include_student_training")};OpenAssessment.EditStudentTrainingView.prototype={description:function(){return{examples:this.exampleDefinitions()}},isEnabled:function(isEnabled){var sel=$("#include_student_training",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},exampleDefinitions:function(xml){var sel=$("#student_training_examples",this.element);return OpenAssessment.Fields.stringField(sel,xml)},getID:function(){return $(this.element).attr("id")}};OpenAssessment.EditExampleBasedAssessmentView=function(element){this.element=element;this.name="example-based-assessment";new OpenAssessment.ToggleControl(this.element,"#ai_assessment_description_closed","#ai_assessment_settings_editor").install("#include_ai_assessment")};OpenAssessment.EditExampleBasedAssessmentView.prototype={description:function(){return{examples:this.exampleDefinitions()}},isEnabled:function(isEnabled){var sel=$("#include_ai_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},exampleDefinitions:function(xml){var sel=$("#ai_training_examples",this.element);return OpenAssessment.Fields.stringField(sel,xml)},getID:function(){return $(this.element).attr("id")}};OpenAssessment.Fields={stringField:function(sel,value){if(typeof value!=="undefined"){sel.val(value)}return sel.val()},datetimeField:function(sel,value){if(typeof value!=="undefined"){sel.val(value)}var fieldValue=sel.val();return fieldValue!==""?fieldValue:null},intField:function(sel,value){if(typeof value!=="undefined"){sel.val(value)}return parseInt(sel.val(),10)},booleanField:function(sel,value){if(typeof value!=="undefined"){sel.prop("checked",value)}return sel.prop("checked")}};OpenAssessment.EditPromptView=function(element){this.element=element};OpenAssessment.EditPromptView.prototype={promptText:function(text){var sel=$("#openassessment_prompt_editor",this.element);return OpenAssessment.Fields.stringField(sel,text)}};OpenAssessment.EditRubricView=function(element){this.element=element;this.criteriaContainer=new OpenAssessment.Container(OpenAssessment.RubricCriterion,{containerElement:$("#openassessment_criterion_list",this.element).get(0),templateElement:$("#openassessment_criterion_template",this.element).get(0),addButtonElement:$("#openassessment_rubric_add_criterion",this.element).get(0),removeButtonClass:"openassessment_criterion_remove_button",containerItemClass:"openassessment_criterion"})};OpenAssessment.EditRubricView.prototype={criteriaDefinition:function(){var criteria=this.criteriaContainer.getItemValues();for(var criterion_idx=0;criterion_idx<criteria.length;criterion_idx++){var criterion=criteria[criterion_idx];criterion.order_num=criterion_idx;for(var option_idx=0;option_idx<criterion.options.length;option_idx++){var option=criterion.options[option_idx];option.order_num=option_idx}}return criteria},feedbackPrompt:function(text){var sel=$("#openassessment_rubric_feedback",this.element);return OpenAssessment.Fields.stringField(sel,text)}};OpenAssessment.EditSettingsView=function(element,assessmentViews){this.settingsElement=element;this.assessmentsElement=$(element).siblings("#openassessment_assessment_module_settings_editors").get(0);this.assessmentViews=assessmentViews};OpenAssessment.EditSettingsView.prototype={displayName:function(name){var sel=$("#openassessment_title_editor",this.settingsElement);return OpenAssessment.Fields.stringField(sel,name)},submissionStart:function(datetime){var sel=$("#openassessment_submission_start_editor",this.settingsElement);return OpenAssessment.Fields.datetimeField(sel,datetime)},submissionDue:function(datetime){var sel=$("#openassessment_submission_start_editor",this.settingsElement);return OpenAssessment.Fields.datetimeField(sel,datetime)},imageSubmissionEnabled:function(isEnabled){var sel=$("#openassessment_submission_image_editor",this.settingsElement);if(typeof isEnabled!=="undefined"){if(isEnabled){sel.val(1)}else{sel.val(0)}}return sel.val()==1},assessmentsDescription:function(){var assessmentDescList=[];var view=this;$(".openassessment_assessment_module_settings_editor",this.assessmentsElement).each(function(){var asmntView=view.assessmentViews[$(this).attr("id")];if(asmntView.isEnabled()){var description=asmntView.description();description["name"]=asmntView.name;assessmentDescList.push(description)}});return assessmentDescList}}; if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}if(typeof OpenAssessment.Server=="undefined"||!OpenAssessment.Server){OpenAssessment.Server=function(runtime,element){this.runtime=runtime;this.element=element};OpenAssessment.Server.prototype={url:function(handler){return this.runtime.handlerUrl(this.element,handler)},render:function(component){var url=this.url("render_"+component);return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html"}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},renderContinuedPeer:function(){var url=this.url("render_peer_assessment");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{continue_grading:true}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},studentInfo:function(student_id){var url=this.url("render_student_info");return $.Deferred(function(defer){$.ajax({url:url,type:"POST",dataType:"html",data:{student_id:student_id}}).done(function(data){defer.resolveWith(this,[data])}).fail(function(data){defer.rejectWith(this,[gettext("This section could not be loaded.")])})}).promise()},submit:function(submission){var url=this.url("submit");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){var success=data[0];if(success){var studentId=data[1];var attemptNum=data[2];defer.resolveWith(this,[studentId,attemptNum])}else{var errorNum=data[1];var errorMsg=data[2];defer.rejectWith(this,[errorNum,errorMsg])}}).fail(function(data){defer.rejectWith(this,["AJAX",gettext("This response could not be submitted.")])})}).promise()},save:function(submission){var url=this.url("save_submission");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({submission:submission})}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This response could not be saved.")])})}).promise()},submitFeedbackOnAssessment:function(text,options){var url=this.url("submit_feedback");var payload=JSON.stringify({feedback_text:text,feedback_options:options});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This feedback could not be submitted.")])})}).promise()},peerAssess:function(optionsSelected,criterionFeedback,overallFeedback){var url=this.url("peer_assess");var payload=JSON.stringify({options_selected:optionsSelected,criterion_feedback:criterionFeedback,overall_feedback:overallFeedback});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})}).promise()},selfAssess:function(optionsSelected){var url=this.url("self_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},trainingAssess:function(optionsSelected){var url=this.url("training_assess");var payload=JSON.stringify({options_selected:optionsSelected});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.corrections])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},scheduleTraining:function(){var url=this.url("schedule_training");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This assessment could not be submitted.")])})})},rescheduleUnfinishedTasks:function(){var url=this.url("reschedule_unfinished_tasks");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:'""'}).done(function(data){if(data.success){defer.resolveWith(this,[data.msg])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("One or more rescheduling tasks failed.")])})})},updateEditorContext:function(kwargs){var url=this.url("update_editor_context");var payload=JSON.stringify({prompt:kwargs.prompt,feedback_prompt:kwargs.feedbackPrompt,title:kwargs.title,submission_start:kwargs.submissionStart,submission_due:kwargs.submissionDue,criteria:kwargs.criteria,assessments:kwargs.assessments});return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolve()}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("This problem could not be saved.")])})}).promise()},checkReleased:function(){var url=this.url("check_released");var payload='""';return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:payload}).done(function(data){if(data.success){defer.resolveWith(this,[data.is_released])}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("The server could not be contacted.")])})}).promise()},getUploadUrl:function(contentType){var url=this.url("upload_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({contentType:contentType})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve upload url.")])})}).promise()},getDownloadUrl:function(){var url=this.url("download_url");return $.Deferred(function(defer){$.ajax({type:"POST",url:url,data:JSON.stringify({})}).done(function(data){if(data.success){defer.resolve(data.url)}else{defer.rejectWith(this,[data.msg])}}).fail(function(data){defer.rejectWith(this,[gettext("Could not retrieve download url.")])})}).promise()}}}if(typeof OpenAssessment=="undefined"||!OpenAssessment){OpenAssessment={}}if(typeof window.gettext==="undefined"){window.gettext=function(text){return text}}OpenAssessment.StudioView=function(runtime,element,server){this.element=element;this.runtime=runtime;this.server=server;this.fixModalHeight();this.initializeTabs();this.promptView=new OpenAssessment.EditPromptView($("#oa_prompt_editor_wrapper",this.element).get(0));var studentTrainingView=new OpenAssessment.EditStudentTrainingView($("#oa_student_training_editor",this.element).get(0));var peerAssessmentView=new OpenAssessment.EditPeerAssessmentView($("#oa_peer_assessment_editor",this.element).get(0));var selfAssessmentView=new OpenAssessment.EditSelfAssessmentView($("#oa_self_assessment_editor",this.element).get(0));var exampleBasedAssessmentView=new OpenAssessment.EditExampleBasedAssessmentView($("#oa_ai_assessment_editor",this.element).get(0));var assessmentLookupDictionary={};assessmentLookupDictionary[studentTrainingView.getID()]=studentTrainingView;assessmentLookupDictionary[peerAssessmentView.getID()]=peerAssessmentView;assessmentLookupDictionary[selfAssessmentView.getID()]=selfAssessmentView;assessmentLookupDictionary[exampleBasedAssessmentView.getID()]=exampleBasedAssessmentView;this.settingsView=new OpenAssessment.EditSettingsView($("#oa_basic_settings_editor",this.element).get(0),assessmentLookupDictionary);this.rubricView=new OpenAssessment.EditRubricView($("#oa_rubric_editor_wrapper",this.element).get(0));$(".openassessment_save_button",this.element).click($.proxy(this.save,this));$(".openassessment_cancel_button",this.element).click($.proxy(this.cancel,this));this.initializeSortableAssessments()};OpenAssessment.StudioView.prototype={fixModalHeight:function(){$(this.element).addClass("openassessment_full_height").parentsUntil(".modal-window").addClass("openassessment_full_height");$(this.element).closest(".modal-window").addClass("openassessment_modal_window")},initializeTabs:function(){if(typeof OpenAssessment.lastOpenEditingTab==="undefined"){OpenAssessment.lastOpenEditingTab=0}$(".openassessment_editor_content_and_tabs",this.element).tabs().tabs("option","active",OpenAssessment.lastOpenEditingTab)},saveTabState:function(){var tabElement=$(".openassessment_editor_content_and_tabs",this.element);OpenAssessment.lastOpenEditingTab=tabElement.tabs("option","active")},initializeSortableAssessments:function(){var view=this;$("#openassessment_assessment_module_settings_editors",view.element).sortable({start:function(event,ui){$(".openassessment_assessment_module_editor",view.element).hide();var targetHeight="auto";ui.placeholder.height(targetHeight);ui.helper.height(targetHeight);$("#openassessment_assessment_module_settings_editors",view.element).sortable("refresh").sortable("refreshPositions")},stop:function(event,ui){$(".openassessment_assessment_module_editor",view.element).show()},snap:true,axis:"y",handle:".drag-handle",cursorAt:{top:20}});$("#openassessment_assessment_module_settings_editors",view.element).disableSelection()},save:function(){var view=this;this.saveTabState();this.server.checkReleased().done(function(isReleased){if(isReleased){view.confirmPostReleaseUpdate($.proxy(view.updateEditorContext,view))}else{view.updateEditorContext()}}).fail(function(errMsg){view.showError(errMsg)})},confirmPostReleaseUpdate:function(onConfirm){var msg=gettext("This problem has already been released. Any changes will apply only to future assessments.");if(confirm(msg)){onConfirm()}},updateEditorContext:function(){this.runtime.notify("save",{state:"start"});var view=this;this.server.updateEditorContext({prompt:view.promptView.promptText(),feedbackPrompt:view.rubricView.feedbackPrompt(),criteria:view.rubricView.criteriaDefinition(),title:view.settingsView.displayName(),submissionStart:view.settingsView.submissionStart(),submissionDue:view.settingsView.submissionDue(),assessments:view.settingsView.assessmentsDescription()}).done(function(){view.runtime.notify("save",{state:"end"})}).fail(function(msg){view.showError(msg)})},cancel:function(){this.saveTabState();this.runtime.notify("cancel",{})},showError:function(errorMsg){this.runtime.notify("error",{msg:errorMsg})}};function OpenAssessmentEditor(runtime,element){var server=new OpenAssessment.Server(runtime,element);var view=new OpenAssessment.StudioView(runtime,element,server)}OpenAssessment.EditPeerAssessmentView=function(element){this.element=element;this.name="peer-assessment";new OpenAssessment.ToggleControl(this.element,"#peer_assessment_description_closed","#peer_assessment_settings_editor").install("#include_peer_assessment");this.startDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#peer_assessment_start_date","#peer_assessment_start_time").install();this.dueDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#peer_assessment_due_date","#peer_assessment_due_time").install()};OpenAssessment.EditPeerAssessmentView.prototype={description:function(){return{must_grade:this.mustGradeNum(),must_be_graded_by:this.mustBeGradedByNum(),start:this.startDatetime(),due:this.dueDatetime()}},isEnabled:function(isEnabled){var sel=$("#include_peer_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},mustGradeNum:function(num){var sel=$("#peer_assessment_must_grade",this.element);return OpenAssessment.Fields.intField(sel,num)},mustBeGradedByNum:function(num){var sel=$("#peer_assessment_graded_by",this.element);return OpenAssessment.Fields.intField(sel,num)},startDatetime:function(dateString,timeString){return this.startDatetimeControl.datetime(dateString,timeString)},dueDatetime:function(dateString,timeString){return this.dueDatetimeControl.datetime(dateString,timeString)},getID:function(){return $(this.element).attr("id")}};OpenAssessment.EditSelfAssessmentView=function(element){this.element=element;this.name="self-assessment";new OpenAssessment.ToggleControl(this.element,"#self_assessment_description_closed","#self_assessment_settings_editor").install("#include_self_assessment");this.startDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#self_assessment_start_date","#self_assessment_start_time").install();this.dueDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#self_assessment_due_date","#self_assessment_due_time").install()};OpenAssessment.EditSelfAssessmentView.prototype={description:function(){return{start:this.startDatetime(),due:this.dueDatetime()}},isEnabled:function(isEnabled){var sel=$("#include_self_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},startDatetime:function(dateString,timeString){return this.startDatetimeControl.datetime(dateString,timeString)},dueDatetime:function(dateString,timeString){return this.dueDatetimeControl.datetime(dateString,timeString)},getID:function(){return $(this.element).attr("id")}};OpenAssessment.EditStudentTrainingView=function(element){this.element=element;this.name="student-training";new OpenAssessment.ToggleControl(this.element,"#student_training_description_closed","#student_training_settings_editor").install("#include_student_training")};OpenAssessment.EditStudentTrainingView.prototype={description:function(){return{examples:this.exampleDefinitions()}},isEnabled:function(isEnabled){var sel=$("#include_student_training",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},exampleDefinitions:function(xml){var sel=$("#student_training_examples",this.element);return OpenAssessment.Fields.stringField(sel,xml)},getID:function(){return $(this.element).attr("id")}};OpenAssessment.EditExampleBasedAssessmentView=function(element){this.element=element;this.name="example-based-assessment";new OpenAssessment.ToggleControl(this.element,"#ai_assessment_description_closed","#ai_assessment_settings_editor").install("#include_ai_assessment")};OpenAssessment.EditExampleBasedAssessmentView.prototype={description:function(){return{examples:this.exampleDefinitions()}},isEnabled:function(isEnabled){var sel=$("#include_ai_assessment",this.element);return OpenAssessment.Fields.booleanField(sel,isEnabled)},exampleDefinitions:function(xml){var sel=$("#ai_training_examples",this.element);return OpenAssessment.Fields.stringField(sel,xml)},getID:function(){return $(this.element).attr("id")}};OpenAssessment.Fields={stringField:function(sel,value){if(typeof value!=="undefined"){sel.val(value)}return sel.val()},intField:function(sel,value){if(typeof value!=="undefined"){sel.val(value)}return parseInt(sel.val(),10)},booleanField:function(sel,value){if(typeof value!=="undefined"){sel.prop("checked",value)}return sel.prop("checked")}};OpenAssessment.ToggleControl=function(element,hiddenSelector,shownSelector){this.element=element;this.hiddenSelector=hiddenSelector;this.shownSelector=shownSelector};OpenAssessment.ToggleControl.prototype={install:function(checkboxSelector){$(checkboxSelector,this.element).change(this,function(event){var control=event.data;if(this.checked){control.show()}else{control.hide()}});return this},show:function(){$(this.hiddenSelector,this.element).addClass("is--hidden");$(this.shownSelector,this.element).removeClass("is--hidden")},hide:function(){$(this.hiddenSelector,this.element).removeClass("is--hidden");$(this.shownSelector,this.element).addClass("is--hidden")}};OpenAssessment.DatetimeControl=function(element,datePicker,timePicker){this.element=element;this.datePicker=datePicker;this.timePicker=timePicker};OpenAssessment.DatetimeControl.prototype={install:function(){var dateString=$(this.datePicker,this.element).val();$(this.datePicker,this.element).datepicker({showButtonPanel:true}).datepicker("option","dateFormat","yy-mm-dd").datepicker("setDate",dateString);$(this.timePicker,this.element).timepicker({timeFormat:"H:i",step:60});return this},datetime:function(dateString,timeString){var datePickerSel=$(this.datePicker,this.element);var timePickerSel=$(this.timePicker,this.element);if(typeof dateString!=="undefined"){datePickerSel.datepicker("setDate",dateString)}if(typeof timeString!=="undefined"){timePickerSel.val(timeString)}if(datePickerSel.val()===""&&timePickerSel.val()===""){return null}return datePickerSel.val()+"T"+timePickerSel.val()}};OpenAssessment.EditPromptView=function(element){this.element=element};OpenAssessment.EditPromptView.prototype={promptText:function(text){var sel=$("#openassessment_prompt_editor",this.element);return OpenAssessment.Fields.stringField(sel,text)}};OpenAssessment.EditRubricView=function(element){this.element=element;this.criteriaContainer=new OpenAssessment.Container(OpenAssessment.RubricCriterion,{containerElement:$("#openassessment_criterion_list",this.element).get(0),templateElement:$("#openassessment_criterion_template",this.element).get(0),addButtonElement:$("#openassessment_rubric_add_criterion",this.element).get(0),removeButtonClass:"openassessment_criterion_remove_button",containerItemClass:"openassessment_criterion"})};OpenAssessment.EditRubricView.prototype={criteriaDefinition:function(){var criteria=this.criteriaContainer.getItemValues();for(var criterion_idx=0;criterion_idx<criteria.length;criterion_idx++){var criterion=criteria[criterion_idx];criterion.order_num=criterion_idx;for(var option_idx=0;option_idx<criterion.options.length;option_idx++){var option=criterion.options[option_idx];option.order_num=option_idx}}return criteria},feedbackPrompt:function(text){var sel=$("#openassessment_rubric_feedback",this.element);return OpenAssessment.Fields.stringField(sel,text)}};OpenAssessment.EditSettingsView=function(element,assessmentViews){this.settingsElement=element;this.assessmentsElement=$(element).siblings("#openassessment_assessment_module_settings_editors").get(0);this.assessmentViews=assessmentViews;this.startDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#openassessment_submission_start_date","#openassessment_submission_start_time").install();this.dueDatetimeControl=new OpenAssessment.DatetimeControl(this.element,"#openassessment_submission_due_date","#openassessment_submission_due_time").install()};OpenAssessment.EditSettingsView.prototype={displayName:function(name){var sel=$("#openassessment_title_editor",this.settingsElement);return OpenAssessment.Fields.stringField(sel,name)},submissionStart:function(dateString,timeString){return this.startDatetimeControl.datetime(dateString,timeString)},submissionDue:function(dateString,timeString){return this.dueDatetimeControl.datetime(dateString,timeString)},imageSubmissionEnabled:function(isEnabled){var sel=$("#openassessment_submission_image_editor",this.settingsElement);if(typeof isEnabled!=="undefined"){if(isEnabled){sel.val(1)}else{sel.val(0)}}return sel.val()==1},assessmentsDescription:function(){var assessmentDescList=[];var view=this;$(".openassessment_assessment_module_settings_editor",this.assessmentsElement).each(function(){var asmntView=view.assessmentViews[$(this).attr("id")];if(asmntView.isEnabled()){var description=asmntView.description();description["name"]=asmntView.name;assessmentDescList.push(description)}});return assessmentDescList}};
\ No newline at end of file \ No newline at end of file
...@@ -26,7 +26,7 @@ describe("OpenAssessment.Container", function () { ...@@ -26,7 +26,7 @@ describe("OpenAssessment.Container", function () {
templateElement: $("#template").get(0), templateElement: $("#template").get(0),
addButtonElement: $("#add_button").get(0), addButtonElement: $("#add_button").get(0),
removeButtonClass: "remove_button", removeButtonClass: "remove_button",
containerItemClass: "test_item", containerItemClass: "container_item",
} }
); );
}; };
...@@ -40,8 +40,10 @@ describe("OpenAssessment.Container", function () { ...@@ -40,8 +40,10 @@ describe("OpenAssessment.Container", function () {
// so we just define the fixture inline. // so we just define the fixture inline.
setFixtures( setFixtures(
'<div id="container" />' + '<div id="container" />' +
'<div id="template" test_id="">' + '<div id="template">' +
'<div class="remove_button" />' + '<div class="container_item" test_id="">' +
'<div class="remove_button" />' +
'</div>' +
'</div>' + '</div>' +
'<div id="add_button" />' '<div id="add_button" />'
); );
...@@ -142,7 +144,7 @@ describe("OpenAssessment.Container", function () { ...@@ -142,7 +144,7 @@ describe("OpenAssessment.Container", function () {
// Add an item directly to the container element in the DOM, // Add an item directly to the container element in the DOM,
// before initializing the container object. // before initializing the container object.
$("#container").append( $("#container").append(
'<div class="test_item" test_id="0">' + '<div class="container_item" test_id="0">' +
'<div class="remove_button" />' + '<div class="remove_button" />' +
'<div>' '<div>'
); );
......
...@@ -36,8 +36,8 @@ describe("OpenAssessment edit assessment views", function() { ...@@ -36,8 +36,8 @@ describe("OpenAssessment edit assessment views", function() {
it("Loads a description", function() { it("Loads a description", function() {
view.mustGradeNum(1); view.mustGradeNum(1);
view.mustBeGradedByNum(2); view.mustBeGradedByNum(2);
view.startDatetime("2014-01-01T00:00"); view.startDatetime("2014-01-01", "00:00");
view.dueDatetime("2014-03-04T00:00"); view.dueDatetime("2014-03-04", "00:00");
expect(view.description()).toEqual({ expect(view.description()).toEqual({
must_grade: 1, must_grade: 1,
must_be_graded_by: 2, must_be_graded_by: 2,
...@@ -65,8 +65,8 @@ describe("OpenAssessment edit assessment views", function() { ...@@ -65,8 +65,8 @@ describe("OpenAssessment edit assessment views", function() {
it("Enables and disables", function() { testEnableAndDisable(view); }); it("Enables and disables", function() { testEnableAndDisable(view); });
it("Loads a description", function() { it("Loads a description", function() {
view.startDatetime("2014-01-01T00:00"); view.startDatetime("2014-01-01", "00:00");
view.dueDatetime("2014-03-04T00:00"); view.dueDatetime("2014-03-04", "00:00");
expect(view.description()).toEqual({ expect(view.description()).toEqual({
start: "2014-01-01T00:00", start: "2014-01-01T00:00",
due: "2014-03-04T00:00" due: "2014-03-04T00:00"
...@@ -74,8 +74,8 @@ describe("OpenAssessment edit assessment views", function() { ...@@ -74,8 +74,8 @@ describe("OpenAssessment edit assessment views", function() {
}); });
it("Handles default dates", function() { it("Handles default dates", function() {
view.startDatetime(""); view.startDatetime("", "");
view.dueDatetime(""); view.dueDatetime("", "");
expect(view.description().start).toBe(null); expect(view.description().start).toBe(null);
expect(view.description().due).toBe(null); expect(view.description().due).toBe(null);
}); });
...@@ -90,7 +90,8 @@ describe("OpenAssessment edit assessment views", function() { ...@@ -90,7 +90,8 @@ describe("OpenAssessment edit assessment views", function() {
}); });
it("Enables and disables", function() { testEnableAndDisable(view); }); it("Enables and disables", function() { testEnableAndDisable(view); });
it("Loads a description", function() { testLoadXMLExamples(view); }); // This test was deleted because it is obsolete due to Context Changes, but has not yet been
// Replaced by functionality in the JavaScript (which will be tested)
}); });
describe("OpenAssessment.EditExampleBasedAssessmentView", function() { describe("OpenAssessment.EditExampleBasedAssessmentView", function() {
......
...@@ -47,17 +47,17 @@ describe("OpenAssessment.EditSettingsView", function() { ...@@ -47,17 +47,17 @@ describe("OpenAssessment.EditSettingsView", function() {
}); });
it("sets and loads the submission start/due dates", function() { it("sets and loads the submission start/due dates", function() {
view.submissionStart(""); view.submissionStart("", "");
expect(view.submissionStart()).toBe(null); expect(view.submissionStart()).toBe(null);
view.submissionStart("2014-04-01T00:00.0000Z"); view.submissionStart("2014-04-01", "00:00");
expect(view.submissionStart()).toEqual("2014-04-01T00:00.0000Z"); expect(view.submissionStart()).toEqual("2014-04-01T00:00");
view.submissionDue(""); view.submissionDue("", "");
expect(view.submissionDue()).toBe(null); expect(view.submissionDue()).toBe(null);
view.submissionDue("2014-05-02T00:00.0000Z"); view.submissionDue("2014-05-02", "00:00");
expect(view.submissionDue()).toEqual("2014-05-02T00:00.0000Z"); expect(view.submissionDue()).toEqual("2014-05-02T00:00");
}); });
it("sets and loads the image enabled state", function() { it("sets and loads the image enabled state", function() {
......
...@@ -10,11 +10,19 @@ For example, to create a container for an item called "test_item", ...@@ -10,11 +10,19 @@ For example, to create a container for an item called "test_item",
the DOM should look something like: the DOM should look something like:
<div id="test_container" /> <div id="test_container" />
<div id="test_item_template"> <div id="test_item_template">
<div class="test_item_remove_button">Remove</div> <div class="test_item">
<p>This is the default value for the item.</p> <div class="test_item_remove_button">Remove</div>
<p>This is the default value for the item.</p>
</div>
</div> </div>
<div id="test_item_add_button">Add</div> <div id="test_item_add_button">Add</div>
A critical property of this setup is that the element you want to
include/duplicate is wrapped inside of a template element which is
the one that your reference when referring to a template. In the
above example, $("#test_item_template") would be the appropriate
reference to the template.
You can then initialize the container: You can then initialize the container:
>>> var container = $("#test_container").get(0); >>> var container = $("#test_container").get(0);
>>> var template = $("#test_item_template").get(0); >>> var template = $("#test_item_template").get(0);
...@@ -82,7 +90,10 @@ OpenAssessment.Container.prototype = { ...@@ -82,7 +90,10 @@ OpenAssessment.Container.prototype = {
// Copy the template into the container // Copy the template into the container
// Remove any CSS IDs (since now the element is not unique) // Remove any CSS IDs (since now the element is not unique)
// and add the item class so we can find it later. // and add the item class so we can find it later.
// Note that the element we add is the first child of the template element.
// For more on the template structure expected, see the class comment
$(this.templateElement) $(this.templateElement)
.children().first()
.clone() .clone()
.removeAttr('id') .removeAttr('id')
.toggleClass('is--hidden', false) .toggleClass('is--hidden', false)
......
...@@ -19,8 +19,8 @@ OpenAssessment.StudioView = function(runtime, element, server) { ...@@ -19,8 +19,8 @@ OpenAssessment.StudioView = function(runtime, element, server) {
// Resize the editing modal // Resize the editing modal
this.fixModalHeight(); this.fixModalHeight();
// Initialize the tabs // Initializes the tabbing functionality and activates the last used.
$(".openassessment_editor_content_and_tabs", this.element).tabs(); this.initializeTabs();
// Initialize the prompt tab view // Initialize the prompt tab view
this.promptView = new OpenAssessment.EditPromptView( this.promptView = new OpenAssessment.EditPromptView(
...@@ -82,6 +82,36 @@ OpenAssessment.StudioView.prototype = { ...@@ -82,6 +82,36 @@ OpenAssessment.StudioView.prototype = {
}, },
/** /**
Initializes the tabs that seperate the sections of the editor.
Because this function relies on the OpenAssessment Name space, the tab that it first
active will be the one that the USER was presented with, regardless of which editor they
were using. I.E. If I leave Editor A in the settings state, and enter editor B, editor B
will automatically open with the settings state.
**/
initializeTabs: function() {
// If this is the first editor that the user has opened, default to the prompt view.
if (typeof(OpenAssessment.lastOpenEditingTab) === "undefined") {
OpenAssessment.lastOpenEditingTab = 0;
}
// Initialize JQuery UI Tabs, and activates the appropriate tab.
$(".openassessment_editor_content_and_tabs", this.element)
.tabs()
.tabs('option', 'active', OpenAssessment.lastOpenEditingTab);
},
/**
Saves the state of the editing tabs in a variable outside of the scope of the editor.
When the user reopens the editing view, they will be greeted by the same tab that they left.
This code is called by the two paths that we could exit the modal through: Saving and canceling.
**/
saveTabState: function() {
var tabElement = $(".openassessment_editor_content_and_tabs", this.element);
OpenAssessment.lastOpenEditingTab = tabElement.tabs('option', 'active');
},
/**
Installs click listeners which initialize drag and drop functionality for assessment modules. Installs click listeners which initialize drag and drop functionality for assessment modules.
**/ **/
initializeSortableAssessments: function () { initializeSortableAssessments: function () {
...@@ -125,7 +155,7 @@ OpenAssessment.StudioView.prototype = { ...@@ -125,7 +155,7 @@ OpenAssessment.StudioView.prototype = {
**/ **/
save: function () { save: function () {
var view = this; var view = this;
this.saveTabState();
// Check whether the problem has been released; if not, // Check whether the problem has been released; if not,
// warn the user and allow them to cancel. // warn the user and allow them to cancel.
this.server.checkReleased().done( this.server.checkReleased().done(
...@@ -187,7 +217,8 @@ OpenAssessment.StudioView.prototype = { ...@@ -187,7 +217,8 @@ OpenAssessment.StudioView.prototype = {
Cancel editing. Cancel editing.
**/ **/
cancel: function () { cancel: function () {
// Notify the client-side runtime so it will close the editing modal. // Notify the client-side runtime so it will close the editing modal
this.saveTabState();
this.runtime.notify('cancel', {}); this.runtime.notify('cancel', {});
}, },
......
/** /**
Show and hide elements based on a checkbox.
Args:
element (DOM element): The parent element, used to scope the selectors.
hiddenSelector (string): The CSS selector string for elements
to show when the checkbox is in the "off" state.
shownSelector (string): The CSS selector string for elements
to show when the checkbox is in the "on" state.
**/
OpenAssessment.ToggleControl = function(element, hiddenSelector, shownSelector) {
this.element = element;
this.hiddenSelector = hiddenSelector;
this.shownSelector = shownSelector;
};
OpenAssessment.ToggleControl.prototype = {
/**
Install the event handler for the checkbox,
passing in the toggle control object as the event data.
Args:
checkboxSelector (string): The CSS selector string for the checkbox.
Returns:
OpenAssessment.ToggleControl
**/
install: function(checkboxSelector) {
$(checkboxSelector, this.element).change(
this, function(event) {
var control = event.data;
if (this.checked) { control.show(); }
else { control.hide(); }
}
);
return this;
},
show: function() {
$(this.hiddenSelector, this.element).addClass('is--hidden');
$(this.shownSelector, this.element).removeClass('is--hidden');
},
hide: function() {
$(this.hiddenSelector, this.element).removeClass('is--hidden');
$(this.shownSelector, this.element).addClass('is--hidden');
}
};
/**
Interface for editing peer assessment settings. Interface for editing peer assessment settings.
Args: Args:
...@@ -62,11 +12,25 @@ OpenAssessment.EditPeerAssessmentView = function(element) { ...@@ -62,11 +12,25 @@ OpenAssessment.EditPeerAssessmentView = function(element) {
this.element = element; this.element = element;
this.name = "peer-assessment"; this.name = "peer-assessment";
// Configure the toggle checkbox to enable/disable this assessment
new OpenAssessment.ToggleControl( new OpenAssessment.ToggleControl(
this.element, this.element,
"#peer_assessment_description_closed", "#peer_assessment_description_closed",
"#peer_assessment_settings_editor" "#peer_assessment_settings_editor"
).install("#include_peer_assessment"); ).install("#include_peer_assessment");
// Configure the date and time fields
this.startDatetimeControl = new OpenAssessment.DatetimeControl(
this.element,
"#peer_assessment_start_date",
"#peer_assessment_start_time"
).install();
this.dueDatetimeControl = new OpenAssessment.DatetimeControl(
this.element,
"#peer_assessment_due_date",
"#peer_assessment_due_time"
).install();
}; };
OpenAssessment.EditPeerAssessmentView.prototype = { OpenAssessment.EditPeerAssessmentView.prototype = {
...@@ -141,28 +105,28 @@ OpenAssessment.EditPeerAssessmentView.prototype = { ...@@ -141,28 +105,28 @@ OpenAssessment.EditPeerAssessmentView.prototype = {
Get or set the start date and time of the assessment. Get or set the start date and time of the assessment.
Args: Args:
datetime (string, optional): If provided, set the datetime to this value. dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns: Returns:
string (ISO-formatted UTC datetime) string (ISO-formatted UTC datetime)
**/ **/
startDatetime: function(datetime) { startDatetime: function(dateString, timeString) {
var sel = $("#peer_assessment_start_date", this.element); return this.startDatetimeControl.datetime(dateString, timeString);
return OpenAssessment.Fields.datetimeField(sel, datetime);
}, },
/** /**
Get or set the due date and time of the assessment. Get or set the due date and time of the assessment.
Args: Args:
datetime (string, optional): If provided, set the datetime to this value. dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns: Returns:
string (ISO-formatted UTC datetime) string (ISO-formatted UTC datetime)
**/ **/
dueDatetime: function(datetime) { dueDatetime: function(dateString, timeString) {
var sel = $("#peer_assessment_due_date", this.element); return this.dueDatetimeControl.datetime(dateString, timeString);
return OpenAssessment.Fields.datetimeField(sel, datetime);
}, },
/** /**
...@@ -191,11 +155,25 @@ OpenAssessment.EditSelfAssessmentView = function(element) { ...@@ -191,11 +155,25 @@ OpenAssessment.EditSelfAssessmentView = function(element) {
this.element = element; this.element = element;
this.name = "self-assessment"; this.name = "self-assessment";
// Configure the toggle checkbox to enable/disable this assessment
new OpenAssessment.ToggleControl( new OpenAssessment.ToggleControl(
this.element, this.element,
"#self_assessment_description_closed", "#self_assessment_description_closed",
"#self_assessment_settings_editor" "#self_assessment_settings_editor"
).install("#include_self_assessment"); ).install("#include_self_assessment");
// Configure the date and time fields
this.startDatetimeControl = new OpenAssessment.DatetimeControl(
this.element,
"#self_assessment_start_date",
"#self_assessment_start_time"
).install();
this.dueDatetimeControl = new OpenAssessment.DatetimeControl(
this.element,
"#self_assessment_due_date",
"#self_assessment_due_time"
).install();
}; };
OpenAssessment.EditSelfAssessmentView.prototype = { OpenAssessment.EditSelfAssessmentView.prototype = {
...@@ -239,28 +217,28 @@ OpenAssessment.EditSelfAssessmentView.prototype = { ...@@ -239,28 +217,28 @@ OpenAssessment.EditSelfAssessmentView.prototype = {
Get or set the start date and time of the assessment. Get or set the start date and time of the assessment.
Args: Args:
datetime (string, optional): If provided, set the datetime to this value. dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns: Returns:
string (ISO-formatted UTC datetime) string (ISO-formatted UTC datetime)
**/ **/
startDatetime: function(datetime) { startDatetime: function(dateString, timeString) {
var sel = $("#self_assessment_start_date", this.element); return this.startDatetimeControl.datetime(dateString, timeString);
return OpenAssessment.Fields.datetimeField(sel, datetime);
}, },
/** /**
Get or set the due date and time of the assessment. Get or set the due date and time of the assessment.
Args: Args:
datetime (string, optional): If provided, set the datetime to this value. dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns: Returns:
string (ISO-formatted UTC datetime) string (ISO-formatted UTC datetime)
**/ **/
dueDatetime: function(datetime) { dueDatetime: function(dateString, timeString) {
var sel = $("#self_assessment_due_date", this.element); return this.dueDatetimeControl.datetime(dateString, timeString);
return OpenAssessment.Fields.datetimeField(sel, datetime);
}, },
/** /**
......
...@@ -7,12 +7,6 @@ OpenAssessment.Fields = { ...@@ -7,12 +7,6 @@ OpenAssessment.Fields = {
return sel.val(); return sel.val();
}, },
datetimeField: function(sel, value) {
if (typeof(value) !== "undefined") { sel.val(value); }
var fieldValue = sel.val();
return (fieldValue !== "") ? fieldValue : null;
},
intField: function(sel, value) { intField: function(sel, value) {
if (typeof(value) !== "undefined") { sel.val(value); } if (typeof(value) !== "undefined") { sel.val(value); }
return parseInt(sel.val(), 10); return parseInt(sel.val(), 10);
...@@ -23,3 +17,113 @@ OpenAssessment.Fields = { ...@@ -23,3 +17,113 @@ OpenAssessment.Fields = {
return sel.prop("checked"); return sel.prop("checked");
}, },
}; };
/**
Show and hide elements based on a checkbox.
Args:
element (DOM element): The parent element, used to scope the selectors.
hiddenSelector (string): The CSS selector string for elements
to show when the checkbox is in the "off" state.
shownSelector (string): The CSS selector string for elements
to show when the checkbox is in the "on" state.
**/
OpenAssessment.ToggleControl = function(element, hiddenSelector, shownSelector) {
this.element = element;
this.hiddenSelector = hiddenSelector;
this.shownSelector = shownSelector;
};
OpenAssessment.ToggleControl.prototype = {
/**
Install the event handler for the checkbox,
passing in the toggle control object as the event data.
Args:
checkboxSelector (string): The CSS selector string for the checkbox.
Returns:
OpenAssessment.ToggleControl
**/
install: function(checkboxSelector) {
$(checkboxSelector, this.element).change(
this, function(event) {
var control = event.data;
if (this.checked) { control.show(); }
else { control.hide(); }
}
);
return this;
},
show: function() {
$(this.hiddenSelector, this.element).addClass('is--hidden');
$(this.shownSelector, this.element).removeClass('is--hidden');
},
hide: function() {
$(this.hiddenSelector, this.element).removeClass('is--hidden');
$(this.shownSelector, this.element).addClass('is--hidden');
}
};
/**
Date and time input fields.
Args:
element (DOM element): The parent element of the control inputs.
datePicker (string): The CSS selector for the date input field.
timePicker (string): The CSS selector for the time input field.
**/
OpenAssessment.DatetimeControl = function(element, datePicker, timePicker) {
this.element = element;
this.datePicker = datePicker;
this.timePicker = timePicker;
};
OpenAssessment.DatetimeControl.prototype = {
/**
Configure the date and time picker inputs.
Returns:
OpenAssessment.DatetimeControl
**/
install: function() {
var dateString = $(this.datePicker, this.element).val();
$(this.datePicker, this.element).datepicker({ showButtonPanel: true })
.datepicker("option", "dateFormat", "yy-mm-dd")
.datepicker("setDate", dateString);
$(this.timePicker, this.element).timepicker({
timeFormat: 'H:i',
step: 60
});
return this;
},
/**
Get or set the date and time.
Args:
dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns:
ISO-formatted datetime string.
**/
datetime: function(dateString, timeString) {
var datePickerSel = $(this.datePicker, this.element);
var timePickerSel = $(this.timePicker, this.element);
if (typeof(dateString) !== "undefined") { datePickerSel.datepicker("setDate", dateString); }
if (typeof(timeString) !== "undefined") { timePickerSel.val(timeString); }
if (datePickerSel.val() === "" && timePickerSel.val() === "") {
return null;
}
return datePickerSel.val() + "T" + timePickerSel.val();
}
};
\ No newline at end of file
...@@ -13,6 +13,19 @@ OpenAssessment.EditSettingsView = function(element, assessmentViews) { ...@@ -13,6 +13,19 @@ OpenAssessment.EditSettingsView = function(element, assessmentViews) {
this.settingsElement = element; this.settingsElement = element;
this.assessmentsElement = $(element).siblings('#openassessment_assessment_module_settings_editors').get(0); this.assessmentsElement = $(element).siblings('#openassessment_assessment_module_settings_editors').get(0);
this.assessmentViews = assessmentViews; this.assessmentViews = assessmentViews;
// Configure the date and time fields
this.startDatetimeControl = new OpenAssessment.DatetimeControl(
this.element,
"#openassessment_submission_start_date",
"#openassessment_submission_start_time"
).install();
this.dueDatetimeControl = new OpenAssessment.DatetimeControl(
this.element,
"#openassessment_submission_due_date",
"#openassessment_submission_due_time"
).install();
}; };
...@@ -37,30 +50,30 @@ OpenAssessment.EditSettingsView.prototype = { ...@@ -37,30 +50,30 @@ OpenAssessment.EditSettingsView.prototype = {
Get or set the submission start date. Get or set the submission start date.
Args: Args:
datetime (string, optional): If provided, set the datetime. dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns: Returns:
string (ISO-format UTC datetime) string (ISO-format UTC datetime)
**/ **/
submissionStart: function(datetime) { submissionStart: function(dateString, timeString) {
var sel = $("#openassessment_submission_start_editor", this.settingsElement); return this.startDatetimeControl.datetime(dateString, timeString);
return OpenAssessment.Fields.datetimeField(sel, datetime);
}, },
/** /**
Get or set the submission end date. Get or set the submission end date.
Args: Args:
datetime (string, optional): If provided, set the datetime. dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns: Returns:
string (ISO-format UTC datetime) string (ISO-format UTC datetime)
**/ **/
submissionDue: function(datetime) { submissionDue: function(dateString, timeString) {
var sel = $("#openassessment_submission_start_editor", this.settingsElement); return this.dueDatetimeControl.datetime(dateString, timeString);
return OpenAssessment.Fields.datetimeField(sel, datetime);
}, },
/** /**
......
...@@ -747,7 +747,7 @@ ...@@ -747,7 +747,7 @@
width: 58%; width: 58%;
display: inline-block; display: inline-block;
position: absolute; position: absolute;
left: 10px; left: 15px;
height: 100%; height: 100%;
textarea { textarea {
min-height: 90px; min-height: 90px;
...@@ -772,6 +772,7 @@ ...@@ -772,6 +772,7 @@
width: 40%; width: 40%;
display: inline-block; display: inline-block;
float: right; float: right;
min-height: 150px;
.openassessment_training_example_criteria_selections { .openassessment_training_example_criteria_selections {
.comp-setting-entry { .comp-setting-entry {
.wrapper-comp-setting{ .wrapper-comp-setting{
......
...@@ -7,6 +7,8 @@ import copy ...@@ -7,6 +7,8 @@ import copy
import logging import logging
from django.template.loader import get_template from django.template.loader import get_template
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from dateutil.parser import parse as parse_date
import pytz
from voluptuous import MultipleInvalid from voluptuous import MultipleInvalid
from xblock.core import XBlock from xblock.core import XBlock
from xblock.fragment import Fragment from xblock.fragment import Fragment
...@@ -14,6 +16,7 @@ from openassessment.xblock import xml ...@@ -14,6 +16,7 @@ from openassessment.xblock import xml
from openassessment.xblock.validation import validator from openassessment.xblock.validation import validator
from openassessment.xblock.data_conversion import create_rubric_dict from openassessment.xblock.data_conversion import create_rubric_dict
from openassessment.xblock.schema import EDITOR_UPDATE_SCHEMA from openassessment.xblock.schema import EDITOR_UPDATE_SCHEMA
from openassessment.xblock.resolve_dates import resolve_dates
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -62,33 +65,21 @@ class StudioMixin(object): ...@@ -62,33 +65,21 @@ class StudioMixin(object):
'assessments (dict) 'assessments (dict)
""" """
# Copies the rubric assessments so that we can change student # In the authoring GUI, date and time fields should never be null.
# training examples from dict -> str without negatively modifying # Therefore, we need to resolve all "default" dates to datetime objects
# the openassessmentblock definition. # before displaying them in the editor.
# Django Templates cannot handle dict keys with dashes, so we'll convert __, __, date_ranges = resolve_dates(
# the dashes to underscores. self.start, self.due,
[(self.submission_start, self.submission_due)] +
# used_assessments (and its unused counterpart) are lists intended to indicate [(asmnt.get('start'), asmnt.get('due')) for asmnt in self.valid_assessments]
# the order that settings editors should be rendered. Using lists allows a set order
# which django can easily convert into template names.
used_assessments = []
assessments = {}
for assessment in self.rubric_assessments:
name = assessment['name'].replace('-', '_')
used_assessments.append(name)
assessments[name] = copy.deepcopy(assessment)
unused_assessments = {'student_training', 'peer_assessment', 'self_assessment', 'example_based_assessment'}
unused_assessments = unused_assessments - set(used_assessments)
student_training_module = self.get_assessment_module(
'student-training'
) )
if student_training_module:
assessments['training'] = copy.deepcopy(student_training_module)
submission_due = self.submission_due if self.submission_due else '' submission_start, submission_due = date_ranges[0]
submission_start = self.submission_start if self.submission_start else '' assessments = self._assessments_editor_context(date_ranges[1:])
used_assessments = set(assessments.keys()) - {'training'}
all_assessments = set(['student_training', 'peer_assessment', 'self_assessment', 'example_based_assessment'])
unused_assessments = all_assessments - used_assessments
# Every rubric requires one criterion. If there is no criteria # Every rubric requires one criterion. If there is no criteria
# configured for the XBlock, return one empty default criterion, with # configured for the XBlock, return one empty default criterion, with
...@@ -104,7 +95,7 @@ class StudioMixin(object): ...@@ -104,7 +95,7 @@ class StudioMixin(object):
'submission_start': submission_start, 'submission_start': submission_start,
'assessments': assessments, 'assessments': assessments,
'criteria': criteria, 'criteria': criteria,
'feedbackprompt': unicode(self.rubric_feedback_prompt), 'feedbackprompt': self.rubric_feedback_prompt,
'unused_assessments': unused_assessments, 'unused_assessments': unused_assessments,
'used_assessments': used_assessments 'used_assessments': used_assessments
} }
...@@ -182,3 +173,59 @@ class StudioMixin(object): ...@@ -182,3 +173,59 @@ class StudioMixin(object):
'success': True, 'msg': u'', 'success': True, 'msg': u'',
'is_released': self.is_released() 'is_released': self.is_released()
} }
def _assessments_editor_context(self, assessment_dates):
"""
Transform the rubric assessments list into the context
we will pass to the Django template.
Args:
assessment_dates: List of assessment date ranges (tuples of start/end datetimes).
Returns:
dict
"""
assessments = {}
for asmnt, date_range in zip(self.rubric_assessments, assessment_dates):
# Django Templates cannot handle dict keys with dashes, so we'll convert
# the dashes to underscores.
name = asmnt['name']
template_name = name.replace('-', '_')
assessments[template_name] = copy.deepcopy(asmnt)
assessments[template_name]['start'] = date_range[0]
assessments[template_name]['due'] = date_range[1]
# In addition to the data in the student training assessment, we need to include two additional
# pieces of information: a blank context to render the empty template with, and the criteria
# for each example (so we don't have any complicated logic within the template). Though this
# could be accomplished within the template, we are opting to remove logic from the template.
student_training_module = self.get_assessment_module('student-training')
student_training_template = {'answer': ""}
criteria_list = copy.deepcopy(self.rubric_criteria)
for criterion in criteria_list:
criterion['option_selected'] = ""
student_training_template['criteria'] = criteria_list
if student_training_module:
example_list = []
# Adds each example to a modified version of the student training module dictionary.
for example in student_training_module['examples']:
criteria_list = copy.deepcopy(self.rubric_criteria)
# Equivalent to a Join Query, this adds the selected option to the Criterion's dictionary, so that
# it can be easily referenced in the template without searching through the selected options.
for criterion in criteria_list:
for option_selected in example['options_selected']:
if option_selected['criterion'] == criterion['name']:
criterion['option_selected'] = option_selected['option']
example_list.append({
'answer': example['answer'],
'criteria': criteria_list,
})
assessments['training'] = {'examples': example_list, 'template': student_training_template}
# If we don't have student training enabled, we still need to render a single (empty, or default) example
else:
assessments['training'] = {'examples': [student_training_template], 'template': student_training_template}
return assessments
...@@ -18,8 +18,7 @@ ...@@ -18,8 +18,7 @@
} }
], ],
"submission_due": "2014-02-27T09:46", "submission_due": "2014-02-27T09:46",
"submission_start": "2014-02-10T09:46", "submission_start": "2014-02-10T09:46"
"expected_error": "error updating xblock configuration"
}, },
"no_prompt": { "no_prompt": {
...@@ -62,8 +61,7 @@ ...@@ -62,8 +61,7 @@
} }
], ],
"submission_due": "2014-02-27T09:46", "submission_due": "2014-02-27T09:46",
"submission_start": "2014-02-10T09:46", "submission_start": "2014-02-10T09:46"
"expected_error": "error"
}, },
"no_feedback_prompt": { "no_feedback_prompt": {
...@@ -106,8 +104,7 @@ ...@@ -106,8 +104,7 @@
} }
], ],
"submission_due": "2014-02-27T09:46", "submission_due": "2014-02-27T09:46",
"submission_start": "2014-02-10T09:46", "submission_start": "2014-02-10T09:46"
"expected_error": "error"
}, },
"no_submission_due": { "no_submission_due": {
...@@ -150,11 +147,10 @@ ...@@ -150,11 +147,10 @@
"due": null "due": null
} }
], ],
"submission_start": "2014-02-10T09:46", "submission_start": "2014-02-10T09:46"
"expected_error": "error updating xblock configuration"
}, },
"invalid_dates_one": { "invalid_dates": {
"feedback_prompt": "Feedback prompt", "feedback_prompt": "Feedback prompt",
"prompt": "Test Prompt", "prompt": "Test Prompt",
"criteria": [ "criteria": [
...@@ -196,7 +192,7 @@ ...@@ -196,7 +192,7 @@
], ],
"submission_due": "2012-02-27T09:46", "submission_due": "2012-02-27T09:46",
"submission_start": "2015-02-10T09:46", "submission_start": "2015-02-10T09:46",
"expected_error": "cannot be later" "expected_error": "the start date '2015-02-10 09:46:00+00:00' cannot be later than the due date '2012-02-27 09:46:00+00:00'"
}, },
"invalid_dates_two": { "invalid_dates_two": {
...@@ -278,8 +274,7 @@ ...@@ -278,8 +274,7 @@
} }
], ],
"submission_due": null, "submission_due": null,
"submission_start": null, "submission_start": null
"expected_error": "error updating xblock configuration"
}, },
"feedback_missing": { "feedback_missing": {
...@@ -315,8 +310,7 @@ ...@@ -315,8 +310,7 @@
} }
], ],
"submission_due": null, "submission_due": null,
"submission_start": null, "submission_start": null
"expected_error": "error updating xblock configuration"
}, },
"criterion_not_a_dict": { "criterion_not_a_dict": {
...@@ -334,8 +328,7 @@ ...@@ -334,8 +328,7 @@
} }
], ],
"submission_due": null, "submission_due": null,
"submission_start": null, "submission_start": null
"expected_error": "error updating xblock configuration"
}, },
"criteria_missing_keys": { "criteria_missing_keys": {
...@@ -371,8 +364,7 @@ ...@@ -371,8 +364,7 @@
} }
], ],
"submission_due": null, "submission_due": null,
"submission_start": null, "submission_start": null
"expected_error": "error updating xblock configuration"
}, },
"options_not_a_list": { "options_not_a_list": {
...@@ -396,8 +388,7 @@ ...@@ -396,8 +388,7 @@
} }
], ],
"submission_due": null, "submission_due": null,
"submission_start": null, "submission_start": null
"expected_error": "error updating xblock configuration"
}, },
"option_not_a_dictionary": { "option_not_a_dictionary": {
...@@ -429,8 +420,7 @@ ...@@ -429,8 +420,7 @@
} }
], ],
"submission_due": null, "submission_due": null,
"submission_start": null, "submission_start": null
"expected_error": "error updating xblock configuration"
}, },
"option_missing_keys": { "option_missing_keys": {
...@@ -466,8 +456,7 @@ ...@@ -466,8 +456,7 @@
} }
], ],
"submission_due": null, "submission_due": null,
"submission_start": null, "submission_start": null
"expected_error": "error updating xblock configuration"
}, },
"option_points_must_be_int": { "option_points_must_be_int": {
...@@ -504,7 +493,297 @@ ...@@ -504,7 +493,297 @@
} }
], ],
"submission_due": null, "submission_due": null,
"submission_start": null, "submission_start": null
"expected_error": "error updating xblock configuration" },
"student_training_example_missing_answer": {
"criteria": [
{
"order_num": 0,
"name": "тєѕт ¢яιтєяιση",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "Ṅö",
"explanation": "Ṅö explanation"
},
{
"order_num": 1,
"points": 2,
"name": "sǝʎ",
"explanation": "sǝʎ explanation"
}
],
"feedback": "required"
}
],
"prompt": "My new prompt.",
"feedback_prompt": "Feedback prompt",
"submission_due": "4014-02-27T09:46",
"submission_start": "4014-02-10T09:46",
"title": "My new title.",
"assessments": [
{
"name": "student-training",
"examples": [
{
"options_selected": [
{ "criterion": "тєѕт ¢яιтєяιση", "option": "Ṅö" }
]
}
]
},
{
"name": "peer-assessment",
"must_grade": 5,
"must_be_graded_by": 3,
"start": null,
"due": "4014-03-10T00:00"
}
]
},
"student_training_example_missing_options_selected": {
"criteria": [
{
"order_num": 0,
"name": "тєѕт ¢яιтєяιση",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "Ṅö",
"explanation": "Ṅö explanation"
},
{
"order_num": 1,
"points": 2,
"name": "sǝʎ",
"explanation": "sǝʎ explanation"
}
],
"feedback": "required"
}
],
"prompt": "My new prompt.",
"feedback_prompt": "Feedback prompt",
"submission_due": "4014-02-27T09:46",
"submission_start": "4014-02-10T09:46",
"title": "My new title.",
"assessments": [
{
"name": "student-training",
"examples": [
{
"answer": "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ"
}
]
},
{
"name": "peer-assessment",
"must_grade": 5,
"must_be_graded_by": 3,
"start": null,
"due": "4014-03-10T00:00"
}
]
},
"student_training_example_missing_criterion": {
"criteria": [
{
"order_num": 0,
"name": "тєѕт ¢яιтєяιση",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "Ṅö",
"explanation": "Ṅö explanation"
},
{
"order_num": 1,
"points": 2,
"name": "sǝʎ",
"explanation": "sǝʎ explanation"
}
],
"feedback": "required"
}
],
"prompt": "My new prompt.",
"feedback_prompt": "Feedback prompt",
"submission_due": "4014-02-27T09:46",
"submission_start": "4014-02-10T09:46",
"title": "My new title.",
"assessments": [
{
"name": "student-training",
"examples": [
{
"answer": "This is another answer",
"options_selected": [
{ "option": "sǝʎ" }
]
}
]
},
{
"name": "peer-assessment",
"must_grade": 5,
"must_be_graded_by": 3,
"start": null,
"due": "4014-03-10T00:00"
}
]
},
"student_training_example_missing_option": {
"criteria": [
{
"order_num": 0,
"name": "тєѕт ¢яιтєяιση",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "Ṅö",
"explanation": "Ṅö explanation"
},
{
"order_num": 1,
"points": 2,
"name": "sǝʎ",
"explanation": "sǝʎ explanation"
}
],
"feedback": "required"
}
],
"prompt": "My new prompt.",
"feedback_prompt": "Feedback prompt",
"submission_due": "4014-02-27T09:46",
"submission_start": "4014-02-10T09:46",
"title": "My new title.",
"assessments": [
{
"name": "student-training",
"examples": [
{
"answer": "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ",
"options_selected": [
{ "criterion": "тєѕт ¢яιтєяιση" }
]
}
]
},
{
"name": "peer-assessment",
"must_grade": 5,
"must_be_graded_by": 3,
"start": null,
"due": "4014-03-10T00:00"
}
]
},
"student_training_no_examples": {
"criteria": [
{
"order_num": 0,
"name": "тєѕт ¢яιтєяιση",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "Ṅö",
"explanation": "Ṅö explanation"
},
{
"order_num": 1,
"points": 2,
"name": "sǝʎ",
"explanation": "sǝʎ explanation"
}
],
"feedback": "required"
}
],
"prompt": "My new prompt.",
"feedback_prompt": "Feedback prompt",
"submission_due": "4014-02-27T09:46",
"submission_start": "4014-02-10T09:46",
"title": "My new title.",
"assessments": [
{
"name": "student-training",
"examples": []
},
{
"name": "peer-assessment",
"must_grade": 5,
"must_be_graded_by": 3,
"start": null,
"due": "4014-03-10T00:00"
}
],
"expected_error": "you must provide at least one example response for student training"
},
"student_training_example_does_not_match_rubric": {
"criteria": [
{
"order_num": 0,
"name": "тєѕт ¢яιтєяιση",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "Ṅö",
"explanation": "Ṅö explanation"
},
{
"order_num": 1,
"points": 2,
"name": "sǝʎ",
"explanation": "sǝʎ explanation"
}
],
"feedback": "required"
}
],
"prompt": "My new prompt.",
"feedback_prompt": "Feedback prompt",
"submission_due": "4014-02-27T09:46",
"submission_start": "4014-02-10T09:46",
"title": "My new title.",
"assessments": [
{
"name": "student-training",
"examples": [
{
"answer": "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ",
"options_selected": [
{ "criterion": "Not a criterion!", "option": "Ṅö" }
]
}
]
},
{
"name": "peer-assessment",
"must_grade": 5,
"must_be_graded_by": 3,
"start": null,
"due": "4014-03-10T00:00"
}
],
"expected_error": "example 1 has an extra option"
} }
} }
{ {
"student_training_one_example": { "student_training_one_example": {
"xml": [ "xml": [
"<examples>",
"<example>", "<example>",
"<answer>ẗëṡẗ äṅṡẅëṛ</answer>", "<answer>ẗëṡẗ äṅṡẅëṛ</answer>",
"<select criterion=\"Test criterion\" option=\"Yes\" />", "<select criterion=\"Test criterion\" option=\"Yes\" />",
"</example>" "</example>",
"</examples>"
], ],
"examples": [ "examples": [
{ {
...@@ -21,6 +23,7 @@ ...@@ -21,6 +23,7 @@
"student_training_multiple_examples": { "student_training_multiple_examples": {
"xml": [ "xml": [
"<examples>",
"<example>", "<example>",
"<answer>ẗëṡẗ äṅṡẅëṛ</answer>", "<answer>ẗëṡẗ äṅṡẅëṛ</answer>",
"<select criterion=\"Test criterion\" option=\"Yes\" />", "<select criterion=\"Test criterion\" option=\"Yes\" />",
...@@ -30,7 +33,8 @@ ...@@ -30,7 +33,8 @@
"<answer>äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ</answer>", "<answer>äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ</answer>",
"<select criterion=\"Another test criterion\" option=\"Yes\" />", "<select criterion=\"Another test criterion\" option=\"Yes\" />",
"<select criterion=\"Test criterion\" option=\"No\" />", "<select criterion=\"Test criterion\" option=\"No\" />",
"</example>" "</example>",
"</examples>"
], ],
"examples": [ "examples": [
{ {
......
...@@ -85,5 +85,61 @@ ...@@ -85,5 +85,61 @@
"due": null "due": null
} }
] ]
},
"student_training": {
"criteria": [
{
"order_num": 0,
"name": "тєѕт ¢яιтєяιση",
"prompt": "Test criterion prompt",
"options": [
{
"order_num": 0,
"points": 0,
"name": "Ṅö",
"explanation": "Ṅö explanation"
},
{
"order_num": 1,
"points": 2,
"name": "sǝʎ",
"explanation": "sǝʎ explanation"
}
],
"feedback": "required"
}
],
"prompt": "My new prompt.",
"feedback_prompt": "Feedback prompt",
"submission_due": "4014-02-27T09:46",
"submission_start": "4014-02-10T09:46",
"title": "My new title.",
"assessments": [
{
"name": "student-training",
"examples": [
{
"answer": "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ",
"options_selected": [
{ "criterion": "тєѕт ¢яιтєяιση", "option": "Ṅö" }
]
},
{
"answer": "This is another answer",
"options_selected": [
{ "criterion": "тєѕт ¢яιтєяιση", "option": "sǝʎ" }
]
}
]
},
{
"name": "peer-assessment",
"must_grade": 5,
"must_be_graded_by": 3,
"start": null,
"due": "4014-03-10T00:00"
}
]
} }
} }
...@@ -4,7 +4,6 @@ View-level tests for Studio view of OpenAssessment XBlock. ...@@ -4,7 +4,6 @@ View-level tests for Studio view of OpenAssessment XBlock.
import json import json
import datetime as dt import datetime as dt
import lxml.etree as etree
import pytz import pytz
from ddt import ddt, file_data from ddt import ddt, file_data
from .base import scenario, XBlockHandlerTestCase from .base import scenario, XBlockHandlerTestCase
...@@ -31,7 +30,13 @@ class StudioViewTest(XBlockHandlerTestCase): ...@@ -31,7 +30,13 @@ class StudioViewTest(XBlockHandlerTestCase):
@file_data('data/invalid_update_xblock.json') @file_data('data/invalid_update_xblock.json')
@scenario('data/basic_scenario.xml') @scenario('data/basic_scenario.xml')
def test_update_context_invalid_request_data(self, xblock, data): def test_update_context_invalid_request_data(self, xblock, data):
expected_error = data.pop('expected_error') # All schema validation errors have the same error message, so use that as the default
# Remove the expected error from the dictionary so we don't get an unexpected key error.
if 'expected_error' in data:
expected_error = data.pop('expected_error')
else:
expected_error = 'error updating xblock configuration'
xblock.published_date = None xblock.published_date = None
resp = self.request(xblock, 'update_editor_context', json.dumps(data), response_format='json') resp = self.request(xblock, 'update_editor_context', json.dumps(data), response_format='json')
self.assertFalse(resp['success']) self.assertFalse(resp['success'])
......
...@@ -12,8 +12,8 @@ from django.test import TestCase ...@@ -12,8 +12,8 @@ from django.test import TestCase
import ddt import ddt
from openassessment.xblock.openassessmentblock import OpenAssessmentBlock from openassessment.xblock.openassessmentblock import OpenAssessmentBlock
from openassessment.xblock.xml import ( from openassessment.xblock.xml import (
serialize_content, parse_from_xml_str, parse_rubric_xml_str, serialize_content, parse_from_xml_str, parse_rubric_xml,
parse_examples_xml_str, parse_assessments_xml_str, parse_examples_xml, parse_assessments_xml,
serialize_rubric_to_xml_str, serialize_examples_to_xml_str, serialize_rubric_to_xml_str, serialize_examples_to_xml_str,
serialize_assessments_to_xml_str, UpdateFromXmlError serialize_assessments_to_xml_str, UpdateFromXmlError
) )
...@@ -335,7 +335,8 @@ class TestParseRubricFromXml(TestCase): ...@@ -335,7 +335,8 @@ class TestParseRubricFromXml(TestCase):
@ddt.file_data("data/parse_rubric_xml.json") @ddt.file_data("data/parse_rubric_xml.json")
def test_parse_rubric_from_xml(self, data): def test_parse_rubric_from_xml(self, data):
rubric = parse_rubric_xml_str("".join(data['xml'])) xml = etree.fromstring("".join(data['xml']))
rubric = parse_rubric_xml(xml)
self.assertEqual(rubric['prompt'], data['prompt']) self.assertEqual(rubric['prompt'], data['prompt'])
self.assertEqual(rubric['feedbackprompt'], data['feedbackprompt']) self.assertEqual(rubric['feedbackprompt'], data['feedbackprompt'])
...@@ -347,8 +348,8 @@ class TestParseExamplesFromXml(TestCase): ...@@ -347,8 +348,8 @@ class TestParseExamplesFromXml(TestCase):
@ddt.file_data("data/parse_examples_xml.json") @ddt.file_data("data/parse_examples_xml.json")
def test_parse_examples_from_xml(self, data): def test_parse_examples_from_xml(self, data):
examples = parse_examples_xml_str("".join(data['xml'])) xml = etree.fromstring("".join(data['xml']))
examples = parse_examples_xml(xml)
self.assertEqual(examples, data['examples']) self.assertEqual(examples, data['examples'])
@ddt.ddt @ddt.ddt
...@@ -356,8 +357,8 @@ class TestParseAssessmentsFromXml(TestCase): ...@@ -356,8 +357,8 @@ class TestParseAssessmentsFromXml(TestCase):
@ddt.file_data("data/parse_assessments_xml.json") @ddt.file_data("data/parse_assessments_xml.json")
def test_parse_assessments_from_xml(self, data): def test_parse_assessments_from_xml(self, data):
assessments = parse_assessments_xml_str("".join(data['xml'])) xml = etree.fromstring("".join(data['xml']))
assessments = parse_assessments_xml(xml)
self.assertEqual(assessments, data['assessments']) self.assertEqual(assessments, data['assessments'])
...@@ -401,4 +402,3 @@ class TestUpdateFromXml(TestCase): ...@@ -401,4 +402,3 @@ class TestUpdateFromXml(TestCase):
def test_parse_from_xml_error(self, data): def test_parse_from_xml_error(self, data):
with self.assertRaises(UpdateFromXmlError): with self.assertRaises(UpdateFromXmlError):
parse_from_xml_str("".join(data['xml'])) parse_from_xml_str("".join(data['xml']))
...@@ -750,70 +750,6 @@ def parse_from_xml_str(xml): ...@@ -750,70 +750,6 @@ def parse_from_xml_str(xml):
return parse_from_xml(_unicode_to_xml(xml)) return parse_from_xml(_unicode_to_xml(xml))
def parse_rubric_xml_str(xml):
"""
Create a dictionary representation of the OpenAssessment XBlock rubric from
the given XML string.
Args:
xml (unicode): The XML definition of the XBlock's rubric.
Returns:
A dictionary of all rubric configuration.
Raises:
UpdateFromXmlError: The XML definition is invalid.
InvalidRubricError: The rubric was not semantically valid.
"""
return parse_rubric_xml(_unicode_to_xml(xml))
def parse_assessments_xml_str(xml):
"""
Create a dictionary representation of the OpenAssessment XBlock assessments
from the given XML string.
Args:
xml (unicode): The XML definition of the XBlock's assessments.
Returns:
A list of dictionaries representing the deserialized XBlock
configuration for each assessment module.
Raises:
UpdateFromXmlError: The XML definition is invalid.
InvalidAssessmentsError: The assessments are not semantically valid.
"""
return parse_assessments_xml(_unicode_to_xml(xml))
def parse_examples_xml_str(xml):
"""
Create a list representation of the OpenAssessment XBlock assessment
examples from the given XML string.
Args:
xml (unicode): The XML definition of the Assessment module's examples.
Returns:
A list of dictionaries representing the deserialized XBlock
configuration for each assessment example.
Raises:
UpdateFromXmlError: The XML definition is invalid.
"""
# This should work for both wrapped and unwrapped examples. Based on our final configuration (and tests)
# we should handle both cases gracefully.
if "<examples>" not in xml:
xml = u"<examples>" + xml + u"</examples>"
return parse_examples_xml(list(_unicode_to_xml(xml).findall('example')))
def _unicode_to_xml(xml): def _unicode_to_xml(xml):
""" """
Converts unicode string to XML node. Converts unicode string to XML node.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment