diff --git a/cms/templates/widgets/header.html b/cms/templates/widgets/header.html
index c1c05671fa..c0b9f9e3af 100644
--- a/cms/templates/widgets/header.html
+++ b/cms/templates/widgets/header.html
@@ -1,13 +1,14 @@
<%! from django.core.urlresolvers import reverse %>
diff --git a/common/lib/xmodule/xmodule/backcompat_module.py b/common/lib/xmodule/xmodule/backcompat_module.py
index d379ced507..997ad476c4 100644
--- a/common/lib/xmodule/xmodule/backcompat_module.py
+++ b/common/lib/xmodule/xmodule/backcompat_module.py
@@ -5,6 +5,7 @@ from x_module import XModuleDescriptor
from lxml import etree
from functools import wraps
import logging
+import traceback
log = logging.getLogger(__name__)
@@ -12,8 +13,8 @@ log = logging.getLogger(__name__)
def process_includes(fn):
"""
Wraps a XModuleDescriptor.from_xml method, and modifies xml_data to replace
- any immediate child items with the contents of the file that they are
- supposed to include
+ any immediate child items with the contents of the file that they
+ are supposed to include
"""
@wraps(fn)
def from_xml(cls, xml_data, system, org=None, course=None):
@@ -21,23 +22,31 @@ def process_includes(fn):
next_include = xml_object.find('include')
while next_include is not None:
file = next_include.get('file')
- if file is not None:
- try:
- ifp = system.resources_fs.open(file)
- except Exception:
- log.exception('Error in problem xml include: %s' % (etree.tostring(next_include, pretty_print=True)))
- log.exception('Cannot find file %s in %s' % (file, dir))
- raise
- try:
- # read in and convert to XML
- incxml = etree.XML(ifp.read())
- except Exception:
- log.exception('Error in problem xml include: %s' % (etree.tostring(next_include, pretty_print=True)))
- log.exception('Cannot parse XML in %s' % (file))
- raise
+ parent = next_include.getparent()
+
+ if file is None:
+ continue
+
+ try:
+ ifp = system.resources_fs.open(file)
+ # read in and convert to XML
+ incxml = etree.XML(ifp.read())
+
# insert new XML into tree in place of inlcude
- parent = next_include.getparent()
parent.insert(parent.index(next_include), incxml)
+ except Exception:
+ msg = "Error in problem xml include: %s" % (etree.tostring(next_include, pretty_print=True))
+ log.exception(msg)
+ parent = next_include.getparent()
+
+ errorxml = etree.Element('error')
+ messagexml = etree.SubElement(errorxml, 'message')
+ messagexml.text = msg
+ stackxml = etree.SubElement(errorxml, 'stacktrace')
+ stackxml.text = traceback.format_exc()
+
+ # insert error XML in place of include
+ parent.insert(parent.index(next_include), errorxml)
parent.remove(next_include)
next_include = xml_object.find('include')
@@ -50,8 +59,8 @@ class SemanticSectionDescriptor(XModuleDescriptor):
@process_includes
def from_xml(cls, xml_data, system, org=None, course=None):
"""
- Removes sections single child elements in favor of just embedding the child element
-
+ Removes sections with single child elements in favor of just embedding
+ the child element
"""
xml_object = etree.fromstring(xml_data)
@@ -76,7 +85,6 @@ class TranslateCustomTagDescriptor(XModuleDescriptor):
xml_object = etree.fromstring(xml_data)
tag = xml_object.tag
xml_object.tag = 'customtag'
- impl = etree.SubElement(xml_object, 'impl')
- impl.text = tag
+ xml_object.attrib['impl'] = tag
return system.process_xml(etree.tostring(xml_object))
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index 263e062887..2fae8b94e2 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -67,7 +67,8 @@ class ComplexEncoder(json.JSONEncoder):
class CapaModule(XModule):
'''
- An XModule implementing LonCapa format problems, implemented by way of capa.capa_problem.LoncapaProblem
+ An XModule implementing LonCapa format problems, implemented by way of
+ capa.capa_problem.LoncapaProblem
'''
icon_class = 'problem'
@@ -77,8 +78,10 @@ class CapaModule(XModule):
js_module_name = "Problem"
css = {'scss': [resource_string(__name__, 'css/capa/display.scss')]}
- def __init__(self, system, location, definition, instance_state=None, shared_state=None, **kwargs):
- XModule.__init__(self, system, location, definition, instance_state, shared_state, **kwargs)
+ def __init__(self, system, location, definition, instance_state=None,
+ shared_state=None, **kwargs):
+ XModule.__init__(self, system, location, definition, instance_state,
+ shared_state, **kwargs)
self.attempts = 0
self.max_attempts = None
@@ -133,7 +136,8 @@ class CapaModule(XModule):
seed = None
try:
- self.lcp = LoncapaProblem(self.definition['data'], self.location.html_id(), instance_state, seed=seed, system=self.system)
+ self.lcp = LoncapaProblem(self.definition['data'], self.location.html_id(),
+ instance_state, seed=seed, system=self.system)
except Exception:
msg = 'cannot create LoncapaProblem %s' % self.location.url()
log.exception(msg)
@@ -141,15 +145,20 @@ class CapaModule(XModule):
msg = '
%s
' % msg.replace('<', '<')
msg += '
%s
' % traceback.format_exc().replace('<', '<')
# create a dummy problem with error message instead of failing
- problem_text = 'Problem %s has an error:%s' % (self.location.url(), msg)
- self.lcp = LoncapaProblem(problem_text, self.location.html_id(), instance_state, seed=seed, system=self.system)
+ problem_text = (''
+ 'Problem %s has an error:%s' %
+ (self.location.url(), msg))
+ self.lcp = LoncapaProblem(
+ problem_text, self.location.html_id(),
+ instance_state, seed=seed, system=self.system)
else:
raise
@property
def rerandomize(self):
"""
- Property accessor that returns self.metadata['rerandomize'] in a canonical form
+ Property accessor that returns self.metadata['rerandomize'] in a
+ canonical form
"""
rerandomize = self.metadata.get('rerandomize', 'always')
if rerandomize in ("", "always", "true"):
@@ -203,7 +212,10 @@ class CapaModule(XModule):
except Exception, err:
if self.system.DEBUG:
log.exception(err)
- msg = '[courseware.capa.capa_module] Failed to generate HTML for problem %s' % (self.location.url())
+ msg = (
+ '[courseware.capa.capa_module] '
+ 'Failed to generate HTML for problem %s' %
+ (self.location.url()))
msg += '
Error:
%s
' % str(err).replace('<', '<')
msg += '
%s
' % traceback.format_exc().replace('<', '<')
html = msg
@@ -215,8 +227,8 @@ class CapaModule(XModule):
'weight': self.weight,
}
- # We using strings as truthy values, because the terminology of the check button
- # is context-specific.
+ # We using strings as truthy values, because the terminology of the
+ # check button is context-specific.
check_button = "Grade" if self.max_attempts else "Check"
reset_button = True
save_button = True
@@ -242,7 +254,8 @@ class CapaModule(XModule):
if not self.lcp.done:
reset_button = False
- # We don't need a "save" button if infinite number of attempts and non-randomized
+ # We don't need a "save" button if infinite number of attempts and
+ # non-randomized
if self.max_attempts is None and self.rerandomize != "always":
save_button = False
@@ -339,7 +352,7 @@ class CapaModule(XModule):
No ajax return is needed. Return empty dict.
"""
queuekey = get['queuekey']
- score_msg = get['response']
+ score_msg = get['xqueue_body']
self.lcp.update_score(score_msg, queuekey)
return dict() # No AJAX return is needed
@@ -517,11 +530,13 @@ class CapaModule(XModule):
self.lcp.do_reset()
if self.rerandomize == "always":
- # reset random number generator seed (note the self.lcp.get_state() in next line)
+ # reset random number generator seed (note the self.lcp.get_state()
+ # in next line)
self.lcp.seed = None
self.lcp = LoncapaProblem(self.definition['data'],
- self.location.html_id(), self.lcp.get_state(), system=self.system)
+ self.location.html_id(), self.lcp.get_state(),
+ system=self.system)
event_info['new_state'] = self.lcp.get_state()
self.system.track_function('reset_problem', event_info)
@@ -537,6 +552,7 @@ class CapaDescriptor(RawDescriptor):
module_class = CapaModule
+ # VS[compat]
# TODO (cpennington): Delete this method once all fall 2012 course are being
# edited in the cms
@classmethod
@@ -545,3 +561,7 @@ class CapaDescriptor(RawDescriptor):
'problems/' + path[8:],
path[8:],
]
+ @classmethod
+ def split_to_file(cls, xml_object):
+ '''Problems always written in their own files'''
+ return True
diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py
index a04324237c..dfac1ac9c6 100644
--- a/common/lib/xmodule/xmodule/course_module.py
+++ b/common/lib/xmodule/xmodule/course_module.py
@@ -10,6 +10,7 @@ log = logging.getLogger(__name__)
class CourseDescriptor(SequenceDescriptor):
module_class = SequenceModule
+ metadata_attributes = SequenceDescriptor.metadata_attributes + ('org', 'course')
def __init__(self, system, definition=None, **kwargs):
super(CourseDescriptor, self).__init__(system, definition, **kwargs)
@@ -17,23 +18,40 @@ class CourseDescriptor(SequenceDescriptor):
try:
self.start = time.strptime(self.metadata["start"], "%Y-%m-%dT%H:%M")
except KeyError:
- self.start = time.gmtime(0) # The epoch
- log.critical("Course loaded without a start date. " + str(self.id))
- except ValueError, e:
- self.start = time.gmtime(0) # The epoch
- log.critical("Course loaded with a bad start date. " + str(self.id) + " '" + str(e) + "'")
+ self.start = time.gmtime(0) #The epoch
+ log.critical("Course loaded without a start date. %s", self.id)
+ except ValueError as e:
+ self.start = time.gmtime(0) #The epoch
+ log.critical("Course loaded with a bad start date. %s '%s'",
+ self.id, e)
def has_started(self):
return time.gmtime() > self.start
- @classmethod
- def id_to_location(cls, course_id):
+ @staticmethod
+ def id_to_location(course_id):
+ '''Convert the given course_id (org/course/name) to a location object.
+ Throws ValueError if course_id is of the wrong format.
+ '''
org, course, name = course_id.split('/')
return Location('i4x', org, course, 'course', name)
+ @staticmethod
+ def location_to_id(location):
+ '''Convert a location of a course to a course_id. If location category
+ is not "course", raise a ValueError.
+
+ location: something that can be passed to Location
+ '''
+ loc = Location(location)
+ if loc.category != "course":
+ raise ValueError("{0} is not a course location".format(loc))
+ return "/".join([loc.org, loc.course, loc.name])
+
+
@property
def id(self):
- return "/".join([self.location.org, self.location.course, self.location.name])
+ return self.location_to_id(self.location)
@property
def start_date_text(self):
diff --git a/common/lib/xmodule/xmodule/css/sequence/display.scss b/common/lib/xmodule/xmodule/css/sequence/display.scss
index d2ea986a4c..7658797725 100644
--- a/common/lib/xmodule/xmodule/css/sequence/display.scss
+++ b/common/lib/xmodule/xmodule/css/sequence/display.scss
@@ -3,8 +3,9 @@ nav.sequence-nav {
// import from external sources.
@extend .topbar;
- border-bottom: 1px solid darken($cream, 20%);
- margin-bottom: $body-line-height;
+ border-bottom: 1px solid #ddd;
+ margin: (-(lh())) (-(lh())) lh() (-(lh()));
+ background: #eee;
position: relative;
@include border-top-right-radius(4px);
@@ -12,6 +13,8 @@ nav.sequence-nav {
@include box-sizing(border-box);
display: table;
height: 100%;
+ margin: 0;
+ padding-left: 0;
padding-right: flex-grid(1, 9);
width: 100%;
@@ -20,7 +23,7 @@ nav.sequence-nav {
}
li {
- border-left: 1px solid darken($cream, 20%);
+ border-left: 1px solid #eee;
display: table-cell;
min-width: 20px;
@@ -32,17 +35,15 @@ nav.sequence-nav {
background-repeat: no-repeat;
&:hover {
- background-color: lighten($cream, 3%);
+ background-color: #eee;
}
}
.visited {
- background-color: #DCCDA2;
+ background-color: #ddd;
background-repeat: no-repeat;
- @include box-shadow(inset 0 0 3px darken(#dccda2, 10%));
&:hover {
- background-color: $cream;
background-position: center center;
}
}
@@ -214,7 +215,7 @@ nav.sequence-nav {
&.prev, &.next {
a {
- background-color: darken($cream, 5%);
+ // background-color: darken($cream, 5%);
background-position: center center;
background-repeat: no-repeat;
border-left: 1px solid darken(#f6efd4, 20%);
@@ -241,7 +242,7 @@ nav.sequence-nav {
background-image: url('../images/sequence-nav/previous-icon.png');
&:hover {
- background-color: $cream;
+ // background-color: $cream;
}
}
}
@@ -251,7 +252,7 @@ nav.sequence-nav {
background-image: url('../images/sequence-nav/next-icon.png');
&:hover {
- background-color: $cream;
+ // background-color: $cream;
}
}
}
@@ -273,9 +274,8 @@ nav.sequence-bottom {
ul {
@extend .clearfix;
- background-color: darken(#F6EFD4, 5%);
- background-color: darken($cream, 5%);
- border: 1px solid darken(#f6efd4, 20%);
+ background-color: #eee;
+ border: 1px solid #ddd;
@include border-radius(3px);
@include box-shadow(inset 0 0 0 1px lighten(#f6efd4, 5%));
@include inline-block();
@@ -297,14 +297,13 @@ nav.sequence-bottom {
width: 45px;
&:hover {
- background-color: $cream;
- color: darken($cream, 60%);
+ background-color: #ddd;
+ color: #000;
opacity: .5;
text-decoration: none;
}
&.disabled {
- background-color: lighten($cream, 10%);
opacity: .4;
}
}
diff --git a/common/lib/xmodule/xmodule/css/video/display.scss b/common/lib/xmodule/xmodule/css/video/display.scss
index b7187cff26..789a267755 100644
--- a/common/lib/xmodule/xmodule/css/video/display.scss
+++ b/common/lib/xmodule/xmodule/css/video/display.scss
@@ -114,14 +114,13 @@ div.video {
@extend .dullify;
float: left;
list-style: none;
- margin-right: lh();
+ margin: 0 lh() 0 0;
padding: 0;
li {
float: left;
margin-bottom: 0;
-
a {
border-bottom: none;
border-right: 1px solid #000;
@@ -183,6 +182,8 @@ div.video {
ol.video_speeds {
display: block;
opacity: 1;
+ padding: 0;
+ margin: 0;
}
}
@@ -210,6 +211,7 @@ div.video {
font-weight: normal;
letter-spacing: 1px;
padding: 0 lh(.25) 0 lh(.5);
+ line-height: 46px;
text-transform: uppercase;
}
@@ -218,6 +220,7 @@ div.video {
font-weight: bold;
margin-bottom: 0;
padding: 0 lh(.5) 0 0;
+ line-height: 46px;
}
&:hover, &:active, &:focus {
@@ -422,10 +425,12 @@ div.video {
}
ol.subtitles {
+ padding-left: 0;
float: left;
max-height: 460px;
overflow: auto;
width: flex-grid(3, 9);
+ margin: 0;
li {
border: 0;
diff --git a/common/lib/xmodule/xmodule/errorhandlers.py b/common/lib/xmodule/xmodule/errorhandlers.py
new file mode 100644
index 0000000000..0f97377b2a
--- /dev/null
+++ b/common/lib/xmodule/xmodule/errorhandlers.py
@@ -0,0 +1,45 @@
+import logging
+import sys
+
+log = logging.getLogger(__name__)
+
+def in_exception_handler():
+ '''Is there an active exception?'''
+ return sys.exc_info() != (None, None, None)
+
+def strict_error_handler(msg, exc_info=None):
+ '''
+ Do not let errors pass. If exc_info is not None, ignore msg, and just
+ re-raise. Otherwise, check if we are in an exception-handling context.
+ If so, re-raise. Otherwise, raise Exception(msg).
+
+ Meant for use in validation, where any errors should trap.
+ '''
+ if exc_info is not None:
+ raise exc_info[0], exc_info[1], exc_info[2]
+
+ if in_exception_handler():
+ raise
+
+ raise Exception(msg)
+
+
+def logging_error_handler(msg, exc_info=None):
+ '''Log all errors, but otherwise let them pass, relying on the caller to
+ workaround.'''
+ if exc_info is not None:
+ log.exception(msg, exc_info=exc_info)
+ return
+
+ if in_exception_handler():
+ log.exception(msg)
+ return
+
+ log.error(msg)
+
+
+def ignore_errors_handler(msg, exc_info=None):
+ '''Ignore all errors, relying on the caller to workaround.
+ Meant for use in the LMS, where an error in one part of the course
+ shouldn't bring down the whole system'''
+ pass
diff --git a/common/lib/xmodule/xmodule/exceptions.py b/common/lib/xmodule/xmodule/exceptions.py
index 9107d9dc4d..3db5ceccde 100644
--- a/common/lib/xmodule/xmodule/exceptions.py
+++ b/common/lib/xmodule/xmodule/exceptions.py
@@ -1,5 +1,6 @@
class InvalidDefinitionError(Exception):
pass
+
class NotFoundError(Exception):
pass
diff --git a/common/lib/xmodule/xmodule/html_module.py b/common/lib/xmodule/xmodule/html_module.py
index 97509c6f34..b9bc34aed6 100644
--- a/common/lib/xmodule/xmodule/html_module.py
+++ b/common/lib/xmodule/xmodule/html_module.py
@@ -12,8 +12,10 @@ class HtmlModule(XModule):
def get_html(self):
return self.html
- def __init__(self, system, location, definition, instance_state=None, shared_state=None, **kwargs):
- XModule.__init__(self, system, location, definition, instance_state, shared_state, **kwargs)
+ def __init__(self, system, location, definition,
+ instance_state=None, shared_state=None, **kwargs):
+ XModule.__init__(self, system, location, definition,
+ instance_state, shared_state, **kwargs)
self.html = self.definition['data']
@@ -42,3 +44,8 @@ class HtmlDescriptor(RawDescriptor):
def file_to_xml(cls, file_object):
parser = etree.HTMLParser()
return etree.parse(file_object, parser).getroot()
+
+ @classmethod
+ def split_to_file(cls, xml_object):
+ # never include inline html
+ return True
diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee
index b5a41e3da5..4ee8257e36 100644
--- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee
+++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee
@@ -31,8 +31,20 @@ class @Problem
else
$.postWithPrefix "#{@url}/problem_get", (response) =>
@el.html(response.html)
+ @executeProblemScripts()
@bind()
+ executeProblemScripts: ->
+ @el.find(".script_placeholder").each (index, placeholder) ->
+ s = $("
-
-Lab 2A: Superposition Experiment
-
-
Note: This part of the lab is just to develop your intuition about
-superposition. There are no responses that need to be checked.
-
-
Circuits with multiple sources can be hard to analyze as-is. For example, what is the voltage
-between the two terminals on the right of Figure 1?
-
-
-
-Figure 1. Example multi-source circuit
-
-
-
We can use superposition to make the analysis much easier.
-The circuit in Figure 1 can be decomposed into two separate
-subcircuits: one involving only the voltage source and one involving only the
-current source. We'll analyze each circuit separately and combine the
-results using superposition. Recall that to decompose a circuit for
-analysis, we'll pick each source in turn and set all the other sources
-to zero (i.e., voltage sources become short circuits and current
-sources become open circuits). The circuit above has two sources, so
-the decomposition produces two subcircuits, as shown in Figure 2.
-
-
-
-
-(a) Subcircuit for analyzing contribution of voltage source
-
-
-(b) Subcircuit for analyzing contribution of current source
-
- Figure 2. Decomposition of Figure 1 into subcircuits
-
-
- Let's use the DC analysis capability of the schematic tool to see superposition
-in action. The sliders below control the resistances of R1, R2, R3 and R4 in all
-the diagrams. As you move the sliders, the schematic tool will adjust the appropriate
-resistance, perform a DC analysis and display the node voltages on the diagrams. Here's
-what you want to observe as you play with the sliders:
-
-
-The voltage for a node in Figure 1 is the sum of the voltages for
-that node in Figures 2(a) and 2(b), just as predicted by
-superposition. (Note that due to round-off in the display of the
-voltages, the sum of the displayed voltages in Figure 2 may only be within
-.01 of the voltages displayed in Figure 1.)
-
diff --git a/doc/overview.md b/doc/overview.md
index 88ea3bdb5e..36e22e16eb 100644
--- a/doc/overview.md
+++ b/doc/overview.md
@@ -13,17 +13,17 @@ You should be familiar with the following. If you're not, go read some docs...
- css
- git
- mako templates -- we use these instead of django templates, because they support embedding real python.
-
+
## Other relevant terms
- CAPA -- lon-capa.org -- content management system that has defined a standard for online learning and assessment materials. Many of our materials follow this standard.
- - TODO: add more details / link to relevant docs. lon-capa.org is not immediately intuitive.
+ - TODO: add more details / link to relevant docs. lon-capa.org is not immediately intuitive.
- lcp = loncapa problem
## Parts of the system
- - LMS -- Learning Management System. The student-facing parts of the system. Handles student accounts, displaying videos, tutorials, exercies, problems, etc.
+ - LMS -- Learning Management System. The student-facing parts of the system. Handles student accounts, displaying videos, tutorials, exercies, problems, etc.
- CMS -- Course Management System. The instructor-facing parts of the system. Allows instructors to see and modify their course, add lectures, problems, reorder things, etc.
@@ -42,7 +42,7 @@ You should be familiar with the following. If you're not, go read some docs...
## High Level Entities in the code
-### Common libraries
+### Common libraries
- xmodule: generic learning modules. *x* can be sequence, video, template, html,
vertical, capa, etc. These are the things that one puts inside sections
@@ -51,7 +51,7 @@ You should be familiar with the following. If you're not, go read some docs...
- XModuleDescriptor: This defines the problem and all data and UI needed to edit
that problem. It is unaware of any student data, but can be used to retrieve
an XModule, which is aware of that student state.
-
+
- XModule: The XModule is a problem instance that is particular to a student. It knows
how to render itself to html to display the problem, how to score itself,
and how to handle ajax calls from the front end.
@@ -59,19 +59,25 @@ You should be familiar with the following. If you're not, go read some docs...
- Both XModule and XModuleDescriptor take system context parameters. These are named
ModuleSystem and DescriptorSystem respectively. These help isolate the XModules
from any interactions with external resources that they require.
-
+
For instance, the DescriptorSystem has a function to load an XModuleDescriptor
from a Location object, and the ModuleSystem knows how to render things,
track events, and complain about 404s
- - TODO: document the system context interface--it's different in `x_module.XModule.__init__` and in `x_module tests.py` (do this in the code, not here)
+
+ - `course.xml` format. We use python setuptools to connect supported tags with the descriptors that handle them. See `common/lib/xmodule/setup.py`. There are checking and validation tools in `common/validate`.
+
+ - the xml import+export functionality is in `xml_module.py:XmlDescriptor`, which is a mixin class that's used by the actual descriptor classes.
+
+ - There is a distinction between descriptor _definitions_ that stay the same for any use of that descriptor (e.g. here is what a particular problem is), and _metadata_ describing how that descriptor is used (e.g. whether to allow checking of answers, due date, etc). When reading in `from_xml`, the code pulls out the metadata attributes into a separate structure, and puts it back on export.
+
- in `common/lib/xmodule`
-- capa modules -- defines `LoncapaProblem` and many related things.
+- capa modules -- defines `LoncapaProblem` and many related things.
- in `common/lib/capa`
-### LMS
+### LMS
-The LMS is a django site, with root in `lms/`. It runs in many different environments--the settings files are in `lms/envs`.
+The LMS is a django site, with root in `lms/`. It runs in many different environments--the settings files are in `lms/envs`.
- We use the Django Auth system, including the is_staff and is_superuser flags. User profiles and related code lives in `lms/djangoapps/student/`. There is support for groups of students (e.g. 'want emails about future courses', 'have unenrolled', etc) in `lms/djangoapps/student/models.py`.
@@ -79,19 +85,19 @@ The LMS is a django site, with root in `lms/`. It runs in many different enviro
- `lms/djangoapps/courseware/models.py`
- Core rendering path:
- - `lms/urls.py` points to `courseware.views.index`, which gets module info from the course xml file, pulls list of `StudentModule` objects for this user (to avoid multiple db hits).
+ - `lms/urls.py` points to `courseware.views.index`, which gets module info from the course xml file, pulls list of `StudentModule` objects for this user (to avoid multiple db hits).
- Calls `render_accordion` to render the "accordion"--the display of the course structure.
- To render the current module, calls `module_render.py:render_x_module()`, which gets the `StudentModule` instance, and passes the `StudentModule` state and other system context to the module constructor the get an instance of the appropriate module class for this user.
- calls the module's `.get_html()` method. If the module has nested submodules, render_x_module() will be called again for each.
-
+
- ajax calls go to `module_render.py:modx_dispatch()`, which passes it to the module's `handle_ajax()` function, and then updates the grade and state if they changed.
- [This diagram](https://github.com/MITx/mitx/wiki/MITx-Architecture) visually shows how the clients communicate with problems + modules.
-
-- See `lms/urls.py` for the wirings of urls to views.
+
+- See `lms/urls.py` for the wirings of urls to views.
- Tracking: there is support for basic tracking of client-side events in `lms/djangoapps/track`.
@@ -110,7 +116,7 @@ environments, defined in `cms/envs`.
- _mako_ -- we use this for templates, and have wrapper called mitxmako that makes mako look like the django templating calls.
-We use a fork of django-pipeline to make sure that the js and css always reflect the latest `*.coffee` and `*.sass` files (We're hoping to get our changes merged in the official version soon). This works differently in development and production. Test uses the production settings.
+We use a fork of django-pipeline to make sure that the js and css always reflect the latest `*.coffee` and `*.sass` files (We're hoping to get our changes merged in the official version soon). This works differently in development and production. Test uses the production settings.
In production, the django `collectstatic` command recompiles everything and puts all the generated static files in a static/ dir. A starting point in the code is `django-pipeline/pipeline/packager.py:pack`.
@@ -127,8 +133,6 @@ See `testing.md`.
## TODO:
-- update lms/envs/README.txt
-
- describe our production environment
- describe the front-end architecture, tools, etc. Starting point: `lms/static`
diff --git a/lms/djangoapps/courseware/management/commands/clean_xml.py b/lms/djangoapps/courseware/management/commands/clean_xml.py
new file mode 100644
index 0000000000..7523fd8373
--- /dev/null
+++ b/lms/djangoapps/courseware/management/commands/clean_xml.py
@@ -0,0 +1,171 @@
+import os
+import sys
+import traceback
+
+from filecmp import dircmp
+from fs.osfs import OSFS
+from path import path
+from lxml import etree
+
+from django.core.management.base import BaseCommand
+
+from xmodule.modulestore.xml import XMLModuleStore
+
+
+def traverse_tree(course):
+ '''Load every descriptor in course. Return bool success value.'''
+ queue = [course]
+ while len(queue) > 0:
+ node = queue.pop()
+# print '{0}:'.format(node.location)
+# if 'data' in node.definition:
+# print '{0}'.format(node.definition['data'])
+ queue.extend(node.get_children())
+
+ return True
+
+def make_logging_error_handler():
+ '''Return a tuple (handler, error_list), where
+ the handler appends the message and any exc_info
+ to the error_list on every call.
+ '''
+ errors = []
+
+ def error_handler(msg, exc_info=None):
+ '''Log errors'''
+ if exc_info is None:
+ if sys.exc_info() != (None, None, None):
+ exc_info = sys.exc_info()
+
+ errors.append((msg, exc_info))
+
+ return (error_handler, errors)
+
+
+def export(course, export_dir):
+ """Export the specified course to course_dir. Creates dir if it doesn't exist.
+ Overwrites files, does not clean out dir beforehand.
+ """
+ fs = OSFS(export_dir, create=True)
+ if not fs.isdirempty('.'):
+ print ('WARNING: Directory {dir} not-empty.'
+ ' May clobber/confuse things'.format(dir=export_dir))
+
+ try:
+ xml = course.export_to_xml(fs)
+ with fs.open('course.xml', mode='w') as f:
+ f.write(xml)
+
+ return True
+ except:
+ print 'Export failed!'
+ traceback.print_exc()
+
+ return False
+
+
+def import_with_checks(course_dir, verbose=True):
+ all_ok = True
+
+ print "Attempting to load '{0}'".format(course_dir)
+
+ course_dir = path(course_dir)
+ data_dir = course_dir.dirname()
+ course_dirs = [course_dir.basename()]
+
+ (error_handler, errors) = make_logging_error_handler()
+ # No default class--want to complain if it doesn't find plugins for any
+ # module.
+ modulestore = XMLModuleStore(data_dir,
+ default_class=None,
+ eager=True,
+ course_dirs=course_dirs,
+ error_handler=error_handler)
+
+ def str_of_err(tpl):
+ (msg, exc_info) = tpl
+ if exc_info is None:
+ return msg
+
+ exc_str = '\n'.join(traceback.format_exception(*exc_info))
+ return '{msg}\n{exc}'.format(msg=msg, exc=exc_str)
+
+ courses = modulestore.get_courses()
+ if len(errors) != 0:
+ all_ok = False
+ print '\n'
+ print "=" * 40
+ print 'ERRORs during import:'
+ print '\n'.join(map(str_of_err,errors))
+ print "=" * 40
+ print '\n'
+
+ n = len(courses)
+ if n != 1:
+ print 'ERROR: Expect exactly 1 course. Loaded {n}: {lst}'.format(
+ n=n, lst=courses)
+ return (False, None)
+
+ course = courses[0]
+
+ #print course
+ validators = (
+ traverse_tree,
+ )
+
+ print "=" * 40
+ print "Running validators..."
+
+ for validate in validators:
+ print 'Running {0}'.format(validate.__name__)
+ all_ok = validate(course) and all_ok
+
+
+ if all_ok:
+ print 'Course passes all checks!'
+ else:
+ print "Course fails some checks. See above for errors."
+ return all_ok, course
+
+
+def check_roundtrip(course_dir):
+ '''Check that import->export leaves the course the same'''
+
+ print "====== Roundtrip import ======="
+ (ok, course) = import_with_checks(course_dir)
+ if not ok:
+ raise Exception("Roundtrip import failed!")
+
+ print "====== Roundtrip export ======="
+ export_dir = course_dir + ".rt"
+ export(course, export_dir)
+
+ # dircmp doesn't do recursive diffs.
+ # diff = dircmp(course_dir, export_dir, ignore=[], hide=[])
+ print "======== Roundtrip diff: ========="
+ os.system("diff -r {0} {1}".format(course_dir, export_dir))
+ print "======== ideally there is no diff above this ======="
+
+
+def clean_xml(course_dir, export_dir):
+ (ok, course) = import_with_checks(course_dir)
+ if ok:
+ export(course, export_dir)
+ check_roundtrip(export_dir)
+ else:
+ print "Did NOT export"
+
+
+
+class Command(BaseCommand):
+ help = """Imports specified course.xml, validate it, then exports in
+ a canonical format.
+
+Usage: clean_xml PATH-TO-COURSE-DIR PATH-TO-OUTPUT-DIR
+"""
+ def handle(self, *args, **options):
+ if len(args) != 2:
+ print Command.help
+ return
+
+ clean_xml(args[0], args[1])
diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py
index 3f111c2953..bf7d1f4c51 100644
--- a/lms/djangoapps/courseware/module_render.py
+++ b/lms/djangoapps/courseware/module_render.py
@@ -56,11 +56,13 @@ def toc_for_course(user, request, course, active_chapter, active_section):
active = (chapter.metadata.get('display_name') == active_chapter and
section.metadata.get('display_name') == active_section)
+ hide_from_toc = section.metadata.get('hide_from_toc', 'false').lower() == 'true'
- sections.append({'name': section.metadata.get('display_name'),
- 'format': section.metadata.get('format', ''),
- 'due': section.metadata.get('due', ''),
- 'active': active})
+ if not hide_from_toc:
+ sections.append({'name': section.metadata.get('display_name'),
+ 'format': section.metadata.get('format', ''),
+ 'due': section.metadata.get('due', ''),
+ 'active': active})
chapters.append({'name': chapter.metadata.get('display_name'),
'sections': sections,
@@ -117,16 +119,18 @@ def get_module(user, request, location, student_module_cache, position=None):
instance_module is a StudentModule specific to this module for this student,
or None if this is an anonymous user
shared_module is a StudentModule specific to all modules with the same
- 'shared_state_key' attribute, or None if the module doesn't elect to
+ 'shared_state_key' attribute, or None if the module does not elect to
share state
'''
descriptor = modulestore().get_item(location)
- instance_module = student_module_cache.lookup(descriptor.category, descriptor.location.url())
+ instance_module = student_module_cache.lookup(descriptor.category,
+ descriptor.location.url())
shared_state_key = getattr(descriptor, 'shared_state_key', None)
if shared_state_key is not None:
- shared_module = student_module_cache.lookup(descriptor.category, shared_state_key)
+ shared_module = student_module_cache.lookup(descriptor.category,
+ shared_state_key)
else:
shared_module = None
@@ -136,10 +140,12 @@ def get_module(user, request, location, student_module_cache, position=None):
# TODO (vshnayder): fix hardcoded urls (use reverse)
# Setup system context for module instance
ajax_url = settings.MITX_ROOT_URL + '/modx/' + descriptor.location.url() + '/'
- xqueue_callback_url = settings.MITX_ROOT_URL + '/xqueue/' + str(user.id) + '/' + descriptor.location.url() + '/'
+ xqueue_callback_url = (settings.MITX_ROOT_URL + '/xqueue/' +
+ str(user.id) + '/' + descriptor.location.url() + '/')
def _get_module(location):
- (module, _, _, _) = get_module(user, request, location, student_module_cache, position)
+ (module, _, _, _) = get_module(user, request, location,
+ student_module_cache, position)
return module
# TODO (cpennington): When modules are shared between courses, the static
diff --git a/lms/static/sass/course/old/print.scss b/lms/djangoapps/courseware/tests/__init__.py
similarity index 100%
rename from lms/static/sass/course/old/print.scss
rename to lms/djangoapps/courseware/tests/__init__.py
diff --git a/lms/djangoapps/courseware/tests/tests.py b/lms/djangoapps/courseware/tests/tests.py
new file mode 100644
index 0000000000..8e9d13f8d5
--- /dev/null
+++ b/lms/djangoapps/courseware/tests/tests.py
@@ -0,0 +1,208 @@
+import copy
+import json
+import os
+
+from pprint import pprint
+
+from django.test import TestCase
+from django.test.client import Client
+from mock import patch, Mock
+from override_settings import override_settings
+from django.conf import settings
+from django.core.urlresolvers import reverse
+from path import path
+
+from student.models import Registration
+from django.contrib.auth.models import User
+
+from xmodule.modulestore.django import modulestore
+import xmodule.modulestore.django
+from xmodule.modulestore import Location
+from xmodule.modulestore.xml_importer import import_from_xml
+
+
+def parse_json(response):
+ """Parse response, which is assumed to be json"""
+ return json.loads(response.content)
+
+
+def user(email):
+ '''look up a user by email'''
+ return User.objects.get(email=email)
+
+
+def registration(email):
+ '''look up registration object by email'''
+ return Registration.objects.get(user__email=email)
+
+
+# A bit of a hack--want mongo modulestore for these tests, until
+# jump_to works with the xmlmodulestore or we have an even better solution
+# NOTE: this means this test requires mongo to be running.
+
+def mongo_store_config(data_dir):
+ return {
+ 'default': {
+ 'ENGINE': 'xmodule.modulestore.mongo.MongoModuleStore',
+ 'OPTIONS': {
+ 'default_class': 'xmodule.raw_module.RawDescriptor',
+ 'host': 'localhost',
+ 'db': 'xmodule',
+ 'collection': 'modulestore',
+ 'fs_root': data_dir,
+ }
+ }
+}
+
+TEST_DATA_DIR = settings.COMMON_TEST_DATA_ROOT
+TEST_DATA_MODULESTORE = mongo_store_config(TEST_DATA_DIR)
+
+REAL_DATA_DIR = settings.GITHUB_REPO_ROOT
+REAL_DATA_MODULESTORE = mongo_store_config(REAL_DATA_DIR)
+
+class ActivateLoginTestCase(TestCase):
+ '''Check that we can activate and log in'''
+
+ def setUp(self):
+ email = 'view@test.com'
+ password = 'foo'
+ self.create_account('viewtest', email, password)
+ self.activate_user(email)
+ self.login(email, password)
+
+ # ============ User creation and login ==============
+
+ def _login(self, email, pw):
+ '''Login. View should always return 200. The success/fail is in the
+ returned json'''
+ resp = self.client.post(reverse('login'),
+ {'email': email, 'password': pw})
+ self.assertEqual(resp.status_code, 200)
+ return resp
+
+ def login(self, email, pw):
+ '''Login, check that it worked.'''
+ resp = self._login(email, pw)
+ data = parse_json(resp)
+ self.assertTrue(data['success'])
+ return resp
+
+ def _create_account(self, username, email, pw):
+ '''Try to create an account. No error checking'''
+ resp = self.client.post('/create_account', {
+ 'username': username,
+ 'email': email,
+ 'password': pw,
+ 'name': 'Fred Weasley',
+ 'terms_of_service': 'true',
+ 'honor_code': 'true',
+ })
+ return resp
+
+ def create_account(self, username, email, pw):
+ '''Create the account and check that it worked'''
+ resp = self._create_account(username, email, pw)
+ self.assertEqual(resp.status_code, 200)
+ data = parse_json(resp)
+ self.assertEqual(data['success'], True)
+
+ # Check both that the user is created, and inactive
+ self.assertFalse(user(email).is_active)
+
+ return resp
+
+ def _activate_user(self, email):
+ '''Look up the activation key for the user, then hit the activate view.
+ No error checking'''
+ activation_key = registration(email).activation_key
+
+ # and now we try to activate
+ resp = self.client.get(reverse('activate', kwargs={'key': activation_key}))
+ return resp
+
+ def activate_user(self, email):
+ resp = self._activate_user(email)
+ self.assertEqual(resp.status_code, 200)
+ # Now make sure that the user is now actually activated
+ self.assertTrue(user(email).is_active)
+
+ def test_activate_login(self):
+ '''The setup function does all the work'''
+ pass
+
+
+class PageLoader(ActivateLoginTestCase):
+ ''' Base class that adds a function to load all pages in a modulestore '''
+
+ def check_pages_load(self, course_name, data_dir, modstore):
+ print "Checking course {0} in {1}".format(course_name, data_dir)
+ import_from_xml(modstore, data_dir, [course_name])
+
+ n = 0
+ num_bad = 0
+ all_ok = True
+ for descriptor in modstore.get_items(
+ Location(None, None, None, None, None)):
+ n += 1
+ print "Checking ", descriptor.location.url()
+ #print descriptor.__class__, descriptor.location
+ resp = self.client.get(reverse('jump_to',
+ kwargs={'location': descriptor.location.url()}))
+ msg = str(resp.status_code)
+
+ if resp.status_code != 200:
+ msg = "ERROR " + msg
+ all_ok = False
+ num_bad += 1
+ print msg
+ self.assertTrue(all_ok) # fail fast
+
+ print "{0}/{1} good".format(n - num_bad, n)
+ self.assertTrue(all_ok)
+
+
+@override_settings(MODULESTORE=TEST_DATA_MODULESTORE)
+class TestCoursesLoadTestCase(PageLoader):
+ '''Check that all pages in test courses load properly'''
+
+ def setUp(self):
+ ActivateLoginTestCase.setUp(self)
+ xmodule.modulestore.django._MODULESTORES = {}
+ xmodule.modulestore.django.modulestore().collection.drop()
+
+ def test_toy_course_loads(self):
+ self.check_pages_load('toy', TEST_DATA_DIR, modulestore())
+
+ def test_full_course_loads(self):
+ self.check_pages_load('full', TEST_DATA_DIR, modulestore())
+
+
+ # ========= TODO: check ajax interaction here too?
+
+
+@override_settings(MODULESTORE=REAL_DATA_MODULESTORE)
+class RealCoursesLoadTestCase(PageLoader):
+ '''Check that all pages in real courses load properly'''
+
+ def setUp(self):
+ ActivateLoginTestCase.setUp(self)
+ xmodule.modulestore.django._MODULESTORES = {}
+ xmodule.modulestore.django.modulestore().collection.drop()
+
+ # TODO: Disabled test for now.. Fix once things are cleaned up.
+ def Xtest_real_courses_loads(self):
+ '''See if any real courses are available at the REAL_DATA_DIR.
+ If they are, check them.'''
+
+ # TODO: adjust staticfiles_dirs
+ if not os.path.isdir(REAL_DATA_DIR):
+ # No data present. Just pass.
+ return
+
+ courses = [course_dir for course_dir in os.listdir(REAL_DATA_DIR)
+ if os.path.isdir(REAL_DATA_DIR / course_dir)]
+ for course in courses:
+ self.check_pages_load(course, REAL_DATA_DIR, modulestore())
+
+
+ # ========= TODO: check ajax interaction here too?
diff --git a/lms/djangoapps/courseware/views.py b/lms/djangoapps/courseware/views.py
index f273778a3c..00fde8a84c 100644
--- a/lms/djangoapps/courseware/views.py
+++ b/lms/djangoapps/courseware/views.py
@@ -20,12 +20,16 @@ from module_render import toc_for_course, get_module, get_section
from models import StudentModuleCache
from student.models import UserProfile
from multicourse import multicourse_settings
+from xmodule.modulestore import Location
+from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError, NoPathToItem
+from xmodule.modulestore.django import modulestore
+from xmodule.course_module import CourseDescriptor
from util.cache import cache, cache_if_anonymous
from student.models import UserTestGroup, CourseEnrollment
from courseware import grades
from courseware.courses import check_course
-from xmodule.modulestore.django import modulestore
+
log = logging.getLogger("mitx.courseware")
@@ -196,65 +200,59 @@ def index(request, course_id, chapter=None, section=None,
if look_for_module:
# TODO (cpennington): Pass the right course in here
- section = get_section(course, chapter, section)
- student_module_cache = StudentModuleCache(request.user, section)
- module, _, _, _ = get_module(request.user, request, section.location, student_module_cache)
- context['content'] = module.get_html()
+ section_descriptor = get_section(course, chapter, section)
+ if section_descriptor is not None:
+ student_module_cache = StudentModuleCache(request.user,
+ section_descriptor)
+ module, _, _, _ = get_module(request.user, request,
+ section_descriptor.location,
+ student_module_cache)
+ context['content'] = module.get_html()
+ else:
+ log.warning("Couldn't find a section descriptor for course_id '{0}',"
+ "chapter '{1}', section '{2}'".format(
+ course_id, chapter, section))
+
result = render_to_response('courseware.html', context)
return result
-
-def jump_to(request, probname=None):
+@ensure_csrf_cookie
+def jump_to(request, location):
'''
- Jump to viewing a specific problem. The problem is specified by a
- problem name - currently the filename (minus .xml) of the problem.
- Maybe this should change to a more generic tag, eg "name" given as
- an attribute in .
+ Show the page that contains a specific location.
- We do the jump by (1) reading course.xml to find the first
- instance of with the given filename, then (2) finding
- the parent element of the problem, then (3) rendering that parent
- element with a specific computed position value (if it is
- ).
+ If the location is invalid, return a 404.
+ If the location is valid, but not present in a course, ?
+
+ If the location is valid, but in a course the current user isn't registered for, ?
+ TODO -- let the index view deal with it?
'''
- # get coursename if stored
- coursename = multicourse_settings.get_coursename_from_request(request)
+ # Complain if the location isn't valid
+ try:
+ location = Location(location)
+ except InvalidLocationError:
+ raise Http404("Invalid location")
- # begin by getting course.xml tree
- xml = content_parser.course_file(request.user, coursename)
+ # Complain if there's not data for this location
+ try:
+ (course_id, chapter, section, position) = modulestore().path_to_location(location)
+ except ItemNotFoundError:
+ raise Http404("No data at this location: {0}".format(location))
+ except NoPathToItem:
+ raise Http404("This location is not in any class: {0}".format(location))
- # look for problem of given name
- pxml = xml.xpath('//problem[@filename="%s"]' % probname)
- if pxml:
- pxml = pxml[0]
-
- # get the parent element
- parent = pxml.getparent()
-
- # figure out chapter and section names
- chapter = None
- section = None
- branch = parent
- for k in range(4): # max depth of recursion
- if branch.tag == 'section':
- section = branch.get('name')
- if branch.tag == 'chapter':
- chapter = branch.get('name')
- branch = branch.getparent()
-
- position = None
- if parent.tag == 'sequential':
- position = parent.index(pxml) + 1 # position in sequence
-
- return index(request,
- course=coursename, chapter=chapter,
- section=section, position=position)
+ return index(request, course_id, chapter, section, position)
@ensure_csrf_cookie
def course_info(request, course_id):
+ '''
+ Display the course's info.html, or 404 if there is no such course.
+
+ Assumes the course_id is in a valid format.
+ '''
course = check_course(course_id)
return render_to_response('info.html', {'course': course})
diff --git a/lms/envs/README.txt b/lms/envs/README.txt
index 7a527b290f..6d1512e6f6 100644
--- a/lms/envs/README.txt
+++ b/lms/envs/README.txt
@@ -1,14 +1,16 @@
-Transitional for moving to new settings scheme.
+Transitional for moving to new settings scheme.
-To use:
- django-admin.py runserver --settings=envs.dev --pythonpath=.
+To use:
+ rake lms
+ or
+ django-admin.py runserver --settings=lms.envs.dev --pythonpath=.
NOTE: Using manage.py will automatically run mitx/settings.py first, regardless
of what you send it for an explicit --settings flag. It still works, but might
-have odd side effects. Using django-admin.py avoids that problem.
+have odd side effects. Using django-admin.py avoids that problem.
django-admin.py is installed by default when you install Django.
To use with gunicorn_django in debug mode:
- gunicorn_django envs/dev.py
+ gunicorn_django lms/envs/dev.py
diff --git a/lms/envs/aws.py b/lms/envs/aws.py
index bd2a0fc389..460ec18d27 100644
--- a/lms/envs/aws.py
+++ b/lms/envs/aws.py
@@ -32,12 +32,12 @@ LOG_DIR = ENV_TOKENS['LOG_DIR']
CACHES = ENV_TOKENS['CACHES']
-for feature,value in ENV_TOKENS.get('MITX_FEATURES', {}).items():
+for feature, value in ENV_TOKENS.get('MITX_FEATURES', {}).items():
MITX_FEATURES[feature] = value
-WIKI_ENABLED = ENV_TOKENS.get('WIKI_ENABLED',WIKI_ENABLED)
+WIKI_ENABLED = ENV_TOKENS.get('WIKI_ENABLED', WIKI_ENABLED)
-LOGGING = get_logger_config(LOG_DIR,
+LOGGING = get_logger_config(LOG_DIR,
logging_env=ENV_TOKENS['LOGGING_ENV'],
syslog_addr=(ENV_TOKENS['SYSLOG_SERVER'], 514),
debug=False)
diff --git a/lms/envs/common.py b/lms/envs/common.py
index c9b44bca40..95daa913e8 100644
--- a/lms/envs/common.py
+++ b/lms/envs/common.py
@@ -6,16 +6,16 @@ MITX_FEATURES[...]. Modules that extend this one can change the feature
configuration in an environment specific config file and re-calculate those
values.
-We should make a method that calls all these config methods so that you just
+We should make a method that calls all these config methods so that you just
make one call at the end of your site-specific dev file to reset all the
dependent variables (like INSTALLED_APPS) for you.
Longer TODO:
-1. Right now our treatment of static content in general and in particular
+1. Right now our treatment of static content in general and in particular
course-specific static content is haphazard.
2. We should have a more disciplined approach to feature flagging, even if it
just means that we stick them in a dict called MITX_FEATURES.
-3. We need to handle configuration for multiple courses. This could be as
+3. We need to handle configuration for multiple courses. This could be as
multiple sites, but we do need a way to map their data assets.
"""
import sys
@@ -42,7 +42,7 @@ MITX_FEATURES = {
'SAMPLE' : False,
'USE_DJANGO_PIPELINE' : True,
'DISPLAY_HISTOGRAMS_TO_STAFF' : True,
- 'REROUTE_ACTIVATION_EMAIL' : False, # nonempty string = address for all activation emails
+ 'REROUTE_ACTIVATION_EMAIL' : False, # nonempty string = address for all activation emails
'DEBUG_LEVEL' : 0, # 0 = lowest level, least verbose, 255 = max level, most verbose
## DO NOT SET TO True IN THIS FILE
@@ -61,7 +61,7 @@ PROJECT_ROOT = path(__file__).abspath().dirname().dirname() # /mitx/lms
REPO_ROOT = PROJECT_ROOT.dirname()
COMMON_ROOT = REPO_ROOT / "common"
ENV_ROOT = REPO_ROOT.dirname() # virtualenv dir /mitx is in
-ASKBOT_ROOT = ENV_ROOT / "askbot-devel"
+ASKBOT_ROOT = REPO_ROOT / "askbot"
COURSES_ROOT = ENV_ROOT / "data"
# FIXME: To support multiple courses, we should walk the courses dir at startup
@@ -85,7 +85,7 @@ MAKO_TEMPLATES['main'] = [PROJECT_ROOT / 'templates',
COMMON_ROOT / 'lib' / 'capa' / 'capa' / 'templates',
COMMON_ROOT / 'djangoapps' / 'pipeline_mako' / 'templates']
-# This is where Django Template lookup is defined. There are a few of these
+# This is where Django Template lookup is defined. There are a few of these
# still left lying around.
TEMPLATE_DIRS = (
PROJECT_ROOT / "templates",
@@ -103,8 +103,8 @@ TEMPLATE_CONTEXT_PROCESSORS = (
)
-# FIXME:
-# We should have separate S3 staged URLs in case we need to make changes to
+# FIXME:
+# We should have separate S3 staged URLs in case we need to make changes to
# these assets and test them.
LIB_URL = '/static/js/'
@@ -120,7 +120,7 @@ STATIC_GRAB = False
DEV_CONTENT = True
# FIXME: Should we be doing this truncation?
-TRACK_MAX_EVENT = 10000
+TRACK_MAX_EVENT = 10000
DEBUG_TRACK_LOG = False
MITX_ROOT_URL = ''
@@ -129,7 +129,7 @@ COURSE_NAME = "6.002_Spring_2012"
COURSE_NUMBER = "6.002x"
COURSE_TITLE = "Circuits and Electronics"
-### Dark code. Should be enabled in local settings for devel.
+### Dark code. Should be enabled in local settings for devel.
ENABLE_MULTICOURSE = False # set to False to disable multicourse display (see lib.util.views.mitxhome)
QUICKEDIT = False
@@ -211,9 +211,9 @@ USE_L10N = True
MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
#################################### AWS #######################################
-# S3BotoStorage insists on a timeout for uploaded assets. We should make it
+# S3BotoStorage insists on a timeout for uploaded assets. We should make it
# permanent instead, but rather than trying to figure out exactly where that
-# setting is, I'm just bumping the expiration time to something absurd (100
+# setting is, I'm just bumping the expiration time to something absurd (100
# years). This is only used if DEFAULT_FILE_STORAGE is overriden to use S3
# in the global settings.py
AWS_QUERYSTRING_EXPIRE = 10 * 365 * 24 * 60 * 60 # 10 years
@@ -279,7 +279,7 @@ MIDDLEWARE_CLASSES = (
# Instead of AuthenticationMiddleware, we use a cached backed version
#'django.contrib.auth.middleware.AuthenticationMiddleware',
'cache_toolbox.middleware.CacheBackedAuthenticationMiddleware',
-
+
'django.contrib.messages.middleware.MessageMiddleware',
'track.middleware.TrackMiddleware',
'mitxmako.middleware.MakoMiddleware',
@@ -301,15 +301,15 @@ STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'
PIPELINE_CSS = {
'application': {
'source_filenames': ['sass/application.scss'],
- 'output_filename': 'css/application.css',
+ 'output_filename': 'css/lms-application.css',
},
'course': {
- 'source_filenames': ['sass/course.scss', 'js/vendor/CodeMirror/codemirror.css', 'css/vendor/jquery.treeview.css'],
- 'output_filename': 'css/course.css',
+ 'source_filenames': ['sass/course.scss', 'js/vendor/CodeMirror/codemirror.css', 'css/vendor/jquery.treeview.css', 'css/vendor/ui-lightness/jquery-ui-1.8.22.custom.css', 'css/vendor/jquery.qtip.min.css'],
+ 'output_filename': 'css/lms-course.css',
},
'ie-fixes': {
'source_filenames': ['sass/ie.scss'],
- 'output_filename': 'css/ie.css',
+ 'output_filename': 'css/lms-ie.css',
},
}
@@ -410,23 +410,23 @@ PIPELINE_JS = {
'js/toggle_login_modal.js',
'js/sticky_filter.js',
],
- 'output_filename': 'js/application.js'
+ 'output_filename': 'js/lms-application.js'
},
'courseware': {
'source_filenames': [pth.replace(PROJECT_ROOT / 'static/', '') for pth in courseware_only_js],
- 'output_filename': 'js/courseware.js'
+ 'output_filename': 'js/lms-courseware.js'
},
'main_vendor': {
'source_filenames': main_vendor_js,
- 'output_filename': 'js/main_vendor.js',
+ 'output_filename': 'js/lms-main_vendor.js',
},
'module-js': {
'source_filenames': module_js_sources,
- 'output_filename': 'js/modules.js',
+ 'output_filename': 'js/lms-modules.js',
},
'spec': {
'source_filenames': [pth.replace(PROJECT_ROOT / 'static/', '') for pth in glob2.glob(PROJECT_ROOT / 'static/coffee/spec/**/*.coffee')],
- 'output_filename': 'js/spec.js'
+ 'output_filename': 'js/lms-spec.js'
}
}
@@ -502,7 +502,7 @@ INSTALLED_APPS = (
# For testing
'django_jasmine',
- # For Askbot
+ # For Askbot
'django.contrib.sitemaps',
'django.contrib.admin',
'django_countries',
diff --git a/lms/envs/test.py b/lms/envs/test.py
index fdfbfb20c4..7d38e1fbb9 100644
--- a/lms/envs/test.py
+++ b/lms/envs/test.py
@@ -12,17 +12,21 @@ from .logsettings import get_logger_config
import os
from path import path
-INSTALLED_APPS = [
- app
- for app
- in INSTALLED_APPS
- if not app.startswith('askbot')
-]
+# can't test start dates with this True, but on the other hand,
+# can test everything else :)
+MITX_FEATURES['DISABLE_START_DATES'] = True
+
+# Need wiki for courseware views to work. TODO (vshnayder): shouldn't need it.
+WIKI_ENABLED = True
+
+# Makes the tests run much faster...
+SOUTH_TESTS_MIGRATE = False # To disable migrations and use syncdb instead
# Nose Test Runner
-INSTALLED_APPS += ['django_nose']
+INSTALLED_APPS += ('django_nose',)
NOSE_ARGS = ['--cover-erase', '--with-xunit', '--with-xcoverage', '--cover-html',
- '--cover-inclusive', '--cover-html-dir', os.environ.get('NOSE_COVER_HTML_DIR', 'cover_html')]
+ '--cover-inclusive', '--cover-html-dir',
+ os.environ.get('NOSE_COVER_HTML_DIR', 'cover_html')]
for app in os.listdir(PROJECT_ROOT / 'djangoapps'):
NOSE_ARGS += ['--cover-package', app]
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
@@ -30,28 +34,27 @@ TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
# Local Directories
TEST_ROOT = path("test_root")
# Want static files in the same dir for running on jenkins.
-STATIC_ROOT = TEST_ROOT / "staticfiles"
+STATIC_ROOT = TEST_ROOT / "staticfiles"
COURSES_ROOT = TEST_ROOT / "data"
DATA_DIR = COURSES_ROOT
-MAKO_TEMPLATES['course'] = [DATA_DIR]
-MAKO_TEMPLATES['sections'] = [DATA_DIR / 'sections']
-MAKO_TEMPLATES['custom_tags'] = [DATA_DIR / 'custom_tags']
-MAKO_TEMPLATES['main'] = [PROJECT_ROOT / 'templates',
- DATA_DIR / 'info',
- DATA_DIR / 'problems']
-LOGGING = get_logger_config(TEST_ROOT / "log",
+LOGGING = get_logger_config(TEST_ROOT / "log",
logging_env="dev",
tracking_filename="tracking.log",
debug=True)
COMMON_TEST_DATA_ROOT = COMMON_ROOT / "test" / "data"
+# Where the content data is checked out. This may not exist on jenkins.
+GITHUB_REPO_ROOT = ENV_ROOT / "data"
-# TODO (cpennington): We need to figure out how envs/test.py can inject things into common.py so that we don't have to repeat this sort of thing
+
+# TODO (cpennington): We need to figure out how envs/test.py can inject things
+# into common.py so that we don't have to repeat this sort of thing
STATICFILES_DIRS = [
COMMON_ROOT / "static",
PROJECT_ROOT / "static",
+ ASKBOT_ROOT / "askbot" / "skins",
]
STATICFILES_DIRS += [
(course_dir, COMMON_TEST_DATA_ROOT / course_dir)
@@ -67,7 +70,7 @@ DATABASES = {
}
CACHES = {
- # This is the cache used for most things. Askbot will not work without a
+ # This is the cache used for most things. Askbot will not work without a
# functioning cache -- it relies on caching to load its settings in places.
# In staging/prod envs, the sessions also live here.
'default': {
diff --git a/lms/envs/with_cms.py b/lms/envs/with_cms.py
new file mode 100644
index 0000000000..b807a0f545
--- /dev/null
+++ b/lms/envs/with_cms.py
@@ -0,0 +1,10 @@
+"""
+Settings for the LMS that runs alongside the CMS on AWS
+"""
+
+from .aws import *
+
+with open(ENV_ROOT / "cms.auth.json") as auth_file:
+ CMS_AUTH_TOKENS = json.load(auth_file)
+
+MODULESTORE = CMS_AUTH_TOKENS['MODULESTORE']
diff --git a/lms/static/.gitignore b/lms/static/.gitignore
index 03f1cdabff..afc42d5e7e 100644
--- a/lms/static/.gitignore
+++ b/lms/static/.gitignore
@@ -5,4 +5,5 @@
*.orig
*.DS_Store
application.css
-ie.css
\ No newline at end of file
+ie.css
+Gemfile.lock
diff --git a/lms/static/sass/course/old/plugins/_jquery.qtip.min.scss b/lms/static/css/vendor/jquery.qtip.min.css
similarity index 100%
rename from lms/static/sass/course/old/plugins/_jquery.qtip.min.scss
rename to lms/static/css/vendor/jquery.qtip.min.css
diff --git a/lms/static/images/ui-bg_flat_0_aaaaaa_40x100.png b/lms/static/images/ui-bg_flat_0_aaaaaa_40x100.png
deleted file mode 100644
index e425e6e46e..0000000000
Binary files a/lms/static/images/ui-bg_flat_0_aaaaaa_40x100.png and /dev/null differ
diff --git a/lms/static/images/ui-bg_flat_0_eeeeee_40x100.png b/lms/static/images/ui-bg_flat_0_eeeeee_40x100.png
deleted file mode 100644
index f1cfaa5636..0000000000
Binary files a/lms/static/images/ui-bg_flat_0_eeeeee_40x100.png and /dev/null differ
diff --git a/lms/static/images/ui-bg_flat_55_ffffff_40x100.png b/lms/static/images/ui-bg_flat_55_ffffff_40x100.png
deleted file mode 100644
index 72d4757363..0000000000
Binary files a/lms/static/images/ui-bg_flat_55_ffffff_40x100.png and /dev/null differ
diff --git a/lms/static/images/ui-bg_flat_75_ffffff_40x100.png b/lms/static/images/ui-bg_flat_75_ffffff_40x100.png
deleted file mode 100644
index 72d4757363..0000000000
Binary files a/lms/static/images/ui-bg_flat_75_ffffff_40x100.png and /dev/null differ
diff --git a/lms/static/images/ui-bg_glass_65_023063_1x400.png b/lms/static/images/ui-bg_glass_65_023063_1x400.png
deleted file mode 100644
index cb030d12ee..0000000000
Binary files a/lms/static/images/ui-bg_glass_65_023063_1x400.png and /dev/null differ
diff --git a/lms/static/images/ui-bg_glass_65_ffffff_1x400.png b/lms/static/images/ui-bg_glass_65_ffffff_1x400.png
deleted file mode 100644
index e7d01fac6a..0000000000
Binary files a/lms/static/images/ui-bg_glass_65_ffffff_1x400.png and /dev/null differ
diff --git a/lms/static/images/ui-bg_highlight-soft_100_7fbcdf_1x100.png b/lms/static/images/ui-bg_highlight-soft_100_7fbcdf_1x100.png
deleted file mode 100644
index 0c1ee5c9cd..0000000000
Binary files a/lms/static/images/ui-bg_highlight-soft_100_7fbcdf_1x100.png and /dev/null differ
diff --git a/lms/static/images/ui-bg_highlight-soft_100_bddeff_1x100.png b/lms/static/images/ui-bg_highlight-soft_100_bddeff_1x100.png
deleted file mode 100644
index 41d7a7d7a7..0000000000
Binary files a/lms/static/images/ui-bg_highlight-soft_100_bddeff_1x100.png and /dev/null differ
diff --git a/lms/static/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png b/lms/static/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png
deleted file mode 100644
index 20bb28e15b..0000000000
Binary files a/lms/static/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png and /dev/null differ
diff --git a/lms/static/images/ui-bg_highlight-soft_25_7fbcdf_1x100.png b/lms/static/images/ui-bg_highlight-soft_25_7fbcdf_1x100.png
deleted file mode 100644
index 903760d875..0000000000
Binary files a/lms/static/images/ui-bg_highlight-soft_25_7fbcdf_1x100.png and /dev/null differ
diff --git a/lms/static/images/ui-bg_highlight-soft_25_bddeff_1x100.png b/lms/static/images/ui-bg_highlight-soft_25_bddeff_1x100.png
deleted file mode 100644
index a4c65deaef..0000000000
Binary files a/lms/static/images/ui-bg_highlight-soft_25_bddeff_1x100.png and /dev/null differ
diff --git a/lms/static/images/ui-bg_highlight-soft_50_7fbcfd_1x100.png b/lms/static/images/ui-bg_highlight-soft_50_7fbcfd_1x100.png
deleted file mode 100644
index 8742d91098..0000000000
Binary files a/lms/static/images/ui-bg_highlight-soft_50_7fbcfd_1x100.png and /dev/null differ
diff --git a/lms/static/images/ui-icons_031634_256x240.png b/lms/static/images/ui-icons_031634_256x240.png
deleted file mode 100644
index 1a38b25a5c..0000000000
Binary files a/lms/static/images/ui-icons_031634_256x240.png and /dev/null differ
diff --git a/lms/static/images/ui-icons_454545_256x240.png b/lms/static/images/ui-icons_454545_256x240.png
deleted file mode 100644
index c7d8883560..0000000000
Binary files a/lms/static/images/ui-icons_454545_256x240.png and /dev/null differ
diff --git a/lms/static/images/ui-icons_adcc80_256x240.png b/lms/static/images/ui-icons_adcc80_256x240.png
deleted file mode 100644
index 28e0801ee2..0000000000
Binary files a/lms/static/images/ui-icons_adcc80_256x240.png and /dev/null differ
diff --git a/lms/static/images/ui-icons_fa720a_256x240.png b/lms/static/images/ui-icons_fa720a_256x240.png
deleted file mode 100644
index ac5171d3ae..0000000000
Binary files a/lms/static/images/ui-icons_fa720a_256x240.png and /dev/null differ
diff --git a/lms/static/images/ui-icons_ffffff_256x240.png b/lms/static/images/ui-icons_ffffff_256x240.png
deleted file mode 100644
index 46df091ffb..0000000000
Binary files a/lms/static/images/ui-icons_ffffff_256x240.png and /dev/null differ
diff --git a/lms/static/images_old/amplifier-slider-handle.png b/lms/static/images_old/amplifier-slider-handle.png
deleted file mode 100644
index 47e3c8d449..0000000000
Binary files a/lms/static/images_old/amplifier-slider-handle.png and /dev/null differ
diff --git a/lms/static/images_old/askbot/comment-vote-up.png b/lms/static/images_old/askbot/comment-vote-up.png
deleted file mode 100644
index 0ce3dcc9e7..0000000000
Binary files a/lms/static/images_old/askbot/comment-vote-up.png and /dev/null differ
diff --git a/lms/static/images_old/askbot/search-icon.png b/lms/static/images_old/askbot/search-icon.png
deleted file mode 100644
index a6d4561b75..0000000000
Binary files a/lms/static/images_old/askbot/search-icon.png and /dev/null differ
diff --git a/lms/static/images_old/askbot/vote-arrow-down-activate.png b/lms/static/images_old/askbot/vote-arrow-down-activate.png
deleted file mode 100644
index 8b0ffc44d0..0000000000
Binary files a/lms/static/images_old/askbot/vote-arrow-down-activate.png and /dev/null differ
diff --git a/lms/static/images_old/askbot/vote-arrow-down.png b/lms/static/images_old/askbot/vote-arrow-down.png
deleted file mode 100644
index aace02ffb2..0000000000
Binary files a/lms/static/images_old/askbot/vote-arrow-down.png and /dev/null differ
diff --git a/lms/static/images_old/askbot/vote-arrow-up-activate.png b/lms/static/images_old/askbot/vote-arrow-up-activate.png
deleted file mode 100644
index 66aa8c9772..0000000000
Binary files a/lms/static/images_old/askbot/vote-arrow-up-activate.png and /dev/null differ
diff --git a/lms/static/images_old/askbot/vote-arrow-up.png b/lms/static/images_old/askbot/vote-arrow-up.png
deleted file mode 100644
index e1920c652e..0000000000
Binary files a/lms/static/images_old/askbot/vote-arrow-up.png and /dev/null differ
diff --git a/lms/static/images_old/askbot/wmd-buttons.png b/lms/static/images_old/askbot/wmd-buttons.png
deleted file mode 100755
index 3013a4ad02..0000000000
Binary files a/lms/static/images_old/askbot/wmd-buttons.png and /dev/null differ
diff --git a/lms/static/images_old/bullet-triangle.png b/lms/static/images_old/bullet-triangle.png
deleted file mode 100644
index cca2bc2ae1..0000000000
Binary files a/lms/static/images_old/bullet-triangle.png and /dev/null differ
diff --git a/lms/static/images_old/calc-icon.png b/lms/static/images_old/calc-icon.png
deleted file mode 100644
index a37423dff1..0000000000
Binary files a/lms/static/images_old/calc-icon.png and /dev/null differ
diff --git a/lms/static/images_old/cc.png b/lms/static/images_old/cc.png
deleted file mode 100644
index 215a496ea1..0000000000
Binary files a/lms/static/images_old/cc.png and /dev/null differ
diff --git a/lms/static/images_old/close-calc-icon.png b/lms/static/images_old/close-calc-icon.png
deleted file mode 100644
index 0a421757bf..0000000000
Binary files a/lms/static/images_old/close-calc-icon.png and /dev/null differ
diff --git a/lms/static/images_old/closed-arrow.png b/lms/static/images_old/closed-arrow.png
deleted file mode 100644
index 4cfb9b9861..0000000000
Binary files a/lms/static/images_old/closed-arrow.png and /dev/null differ
diff --git a/lms/static/images_old/correct-icon.png b/lms/static/images_old/correct-icon.png
deleted file mode 100644
index 5ae7de2a14..0000000000
Binary files a/lms/static/images_old/correct-icon.png and /dev/null differ
diff --git a/lms/static/images_old/css/.xcf b/lms/static/images_old/css/.xcf
deleted file mode 100644
index ea823a0fe1..0000000000
Binary files a/lms/static/images_old/css/.xcf and /dev/null differ
diff --git a/lms/static/images_old/css/bottomWrapper-bg.jpg b/lms/static/images_old/css/bottomWrapper-bg.jpg
deleted file mode 100644
index 7e56627dac..0000000000
Binary files a/lms/static/images_old/css/bottomWrapper-bg.jpg and /dev/null differ
diff --git a/lms/static/images_old/css/footerWrapper-bg.jpg b/lms/static/images_old/css/footerWrapper-bg.jpg
deleted file mode 100644
index 93eba982bf..0000000000
Binary files a/lms/static/images_old/css/footerWrapper-bg.jpg and /dev/null differ
diff --git a/lms/static/images_old/css/hat.jpg b/lms/static/images_old/css/hat.jpg
deleted file mode 100644
index d2b008fcfb..0000000000
Binary files a/lms/static/images_old/css/hat.jpg and /dev/null differ
diff --git a/lms/static/images_old/css/hmenu-sel.jpg b/lms/static/images_old/css/hmenu-sel.jpg
deleted file mode 100644
index d4a0d40ed1..0000000000
Binary files a/lms/static/images_old/css/hmenu-sel.jpg and /dev/null differ
diff --git a/lms/static/images_old/css/hmenu.jpg b/lms/static/images_old/css/hmenu.jpg
deleted file mode 100644
index d0ae8683fc..0000000000
Binary files a/lms/static/images_old/css/hmenu.jpg and /dev/null differ
diff --git a/lms/static/images_old/css/page-bg.jpg b/lms/static/images_old/css/page-bg.jpg
deleted file mode 100644
index 210c04d5a8..0000000000
Binary files a/lms/static/images_old/css/page-bg.jpg and /dev/null differ
diff --git a/lms/static/images_old/css/page-vbg.jpg b/lms/static/images_old/css/page-vbg.jpg
deleted file mode 100644
index 93eba982bf..0000000000
Binary files a/lms/static/images_old/css/page-vbg.jpg and /dev/null differ
diff --git a/lms/static/images_old/css/topBanner-old.xcf b/lms/static/images_old/css/topBanner-old.xcf
deleted file mode 100644
index 32e7472411..0000000000
Binary files a/lms/static/images_old/css/topBanner-old.xcf and /dev/null differ
diff --git a/lms/static/images_old/css/topBanner.jpg b/lms/static/images_old/css/topBanner.jpg
deleted file mode 100644
index b6aa405872..0000000000
Binary files a/lms/static/images_old/css/topBanner.jpg and /dev/null differ
diff --git a/lms/static/images_old/css/topBanner.png b/lms/static/images_old/css/topBanner.png
deleted file mode 100644
index 9524f80837..0000000000
Binary files a/lms/static/images_old/css/topBanner.png and /dev/null differ
diff --git a/lms/static/images_old/css/topBanner.xcf b/lms/static/images_old/css/topBanner.xcf
deleted file mode 100644
index e107747de7..0000000000
Binary files a/lms/static/images_old/css/topBanner.xcf and /dev/null differ
diff --git a/lms/static/images_old/css/topWrapper-bg.jpg b/lms/static/images_old/css/topWrapper-bg.jpg
deleted file mode 100644
index 7a86a1c1c4..0000000000
Binary files a/lms/static/images_old/css/topWrapper-bg.jpg and /dev/null differ
diff --git a/lms/static/images_old/document-download.png b/lms/static/images_old/document-download.png
deleted file mode 100644
index 9cceef2486..0000000000
Binary files a/lms/static/images_old/document-download.png and /dev/null differ
diff --git a/lms/static/images_old/facebook.png b/lms/static/images_old/facebook.png
deleted file mode 100644
index f024b7c8ae..0000000000
Binary files a/lms/static/images_old/facebook.png and /dev/null differ
diff --git a/lms/static/images_old/favicon.ico b/lms/static/images_old/favicon.ico
deleted file mode 100644
index 67203a5c95..0000000000
Binary files a/lms/static/images_old/favicon.ico and /dev/null differ
diff --git a/lms/static/images_old/fullscreen.png b/lms/static/images_old/fullscreen.png
deleted file mode 100644
index e2f9054fe1..0000000000
Binary files a/lms/static/images_old/fullscreen.png and /dev/null differ
diff --git a/lms/static/images_old/incorrect-icon.png b/lms/static/images_old/incorrect-icon.png
deleted file mode 100644
index 0926486ec9..0000000000
Binary files a/lms/static/images_old/incorrect-icon.png and /dev/null differ
diff --git a/lms/static/images_old/info-icon.png b/lms/static/images_old/info-icon.png
deleted file mode 100644
index 736b2f2374..0000000000
Binary files a/lms/static/images_old/info-icon.png and /dev/null differ
diff --git a/lms/static/images_old/linkedin.png b/lms/static/images_old/linkedin.png
deleted file mode 100644
index 34261b05e5..0000000000
Binary files a/lms/static/images_old/linkedin.png and /dev/null differ
diff --git a/lms/static/images_old/marketing/circuits-bg.jpg b/lms/static/images_old/marketing/circuits-bg.jpg
deleted file mode 100644
index c1bb2bae6d..0000000000
Binary files a/lms/static/images_old/marketing/circuits-bg.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/circuits-medium-bg.jpg b/lms/static/images_old/marketing/circuits-medium-bg.jpg
deleted file mode 100644
index a362efc515..0000000000
Binary files a/lms/static/images_old/marketing/circuits-medium-bg.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/course-bg-large.jpg b/lms/static/images_old/marketing/course-bg-large.jpg
deleted file mode 100644
index d73ed705ae..0000000000
Binary files a/lms/static/images_old/marketing/course-bg-large.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/course-bg-medium.jpg b/lms/static/images_old/marketing/course-bg-medium.jpg
deleted file mode 100644
index 0633dd588f..0000000000
Binary files a/lms/static/images_old/marketing/course-bg-medium.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/course-bg-small.jpg b/lms/static/images_old/marketing/course-bg-small.jpg
deleted file mode 100644
index c939c8d604..0000000000
Binary files a/lms/static/images_old/marketing/course-bg-small.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/edx-logo.png b/lms/static/images_old/marketing/edx-logo.png
deleted file mode 100644
index 71dbafc375..0000000000
Binary files a/lms/static/images_old/marketing/edx-logo.png and /dev/null differ
diff --git a/lms/static/images_old/marketing/facebook.png b/lms/static/images_old/marketing/facebook.png
deleted file mode 100644
index d7bca9b628..0000000000
Binary files a/lms/static/images_old/marketing/facebook.png and /dev/null differ
diff --git a/lms/static/images_old/marketing/link-arrow.png b/lms/static/images_old/marketing/link-arrow.png
deleted file mode 100644
index 7d9a4914a3..0000000000
Binary files a/lms/static/images_old/marketing/link-arrow.png and /dev/null differ
diff --git a/lms/static/images_old/marketing/linkedin.png b/lms/static/images_old/marketing/linkedin.png
deleted file mode 100644
index 7658bb3139..0000000000
Binary files a/lms/static/images_old/marketing/linkedin.png and /dev/null differ
diff --git a/lms/static/images_old/marketing/mit-logo.png b/lms/static/images_old/marketing/mit-logo.png
deleted file mode 100644
index 53549ae509..0000000000
Binary files a/lms/static/images_old/marketing/mit-logo.png and /dev/null differ
diff --git a/lms/static/images_old/marketing/shot-1-large.jpg b/lms/static/images_old/marketing/shot-1-large.jpg
deleted file mode 100644
index 21384de85a..0000000000
Binary files a/lms/static/images_old/marketing/shot-1-large.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/shot-1-medium.jpg b/lms/static/images_old/marketing/shot-1-medium.jpg
deleted file mode 100644
index 2deab81dc4..0000000000
Binary files a/lms/static/images_old/marketing/shot-1-medium.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/shot-2-large.jpg b/lms/static/images_old/marketing/shot-2-large.jpg
deleted file mode 100644
index 592c327ec2..0000000000
Binary files a/lms/static/images_old/marketing/shot-2-large.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/shot-3-large.jpg b/lms/static/images_old/marketing/shot-3-large.jpg
deleted file mode 100644
index 34e5134d9d..0000000000
Binary files a/lms/static/images_old/marketing/shot-3-large.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/shot-4-large.jpg b/lms/static/images_old/marketing/shot-4-large.jpg
deleted file mode 100644
index af9550c702..0000000000
Binary files a/lms/static/images_old/marketing/shot-4-large.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/shot-5-large.jpg b/lms/static/images_old/marketing/shot-5-large.jpg
deleted file mode 100644
index b845e6886a..0000000000
Binary files a/lms/static/images_old/marketing/shot-5-large.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/shot-5-medium.jpg b/lms/static/images_old/marketing/shot-5-medium.jpg
deleted file mode 100644
index c236ec1175..0000000000
Binary files a/lms/static/images_old/marketing/shot-5-medium.jpg and /dev/null differ
diff --git a/lms/static/images_old/marketing/twitter.png b/lms/static/images_old/marketing/twitter.png
deleted file mode 100644
index 3747bdce73..0000000000
Binary files a/lms/static/images_old/marketing/twitter.png and /dev/null differ
diff --git a/lms/static/images_old/open-arrow.png b/lms/static/images_old/open-arrow.png
deleted file mode 100644
index 4bedb61081..0000000000
Binary files a/lms/static/images_old/open-arrow.png and /dev/null differ
diff --git a/lms/static/images_old/pause-icon.png b/lms/static/images_old/pause-icon.png
deleted file mode 100644
index e3eac51947..0000000000
Binary files a/lms/static/images_old/pause-icon.png and /dev/null differ
diff --git a/lms/static/images_old/play-icon.png b/lms/static/images_old/play-icon.png
deleted file mode 100644
index 2888b1c271..0000000000
Binary files a/lms/static/images_old/play-icon.png and /dev/null differ
diff --git a/lms/static/images_old/slide-left-icon.png b/lms/static/images_old/slide-left-icon.png
deleted file mode 100644
index ba852870de..0000000000
Binary files a/lms/static/images_old/slide-left-icon.png and /dev/null differ
diff --git a/lms/static/images_old/slide-right-icon.png b/lms/static/images_old/slide-right-icon.png
deleted file mode 100644
index c73e8b3d35..0000000000
Binary files a/lms/static/images_old/slide-right-icon.png and /dev/null differ
diff --git a/lms/static/images_old/slider-bars.png b/lms/static/images_old/slider-bars.png
deleted file mode 100644
index f2e014f4b7..0000000000
Binary files a/lms/static/images_old/slider-bars.png and /dev/null differ
diff --git a/lms/static/images_old/slider-handle.png b/lms/static/images_old/slider-handle.png
deleted file mode 100644
index 94ebe6f0bc..0000000000
Binary files a/lms/static/images_old/slider-handle.png and /dev/null differ
diff --git a/lms/static/images_old/treeview-default.gif b/lms/static/images_old/treeview-default.gif
deleted file mode 100644
index fa3d8239ea..0000000000
Binary files a/lms/static/images_old/treeview-default.gif and /dev/null differ
diff --git a/lms/static/images_old/twitter.png b/lms/static/images_old/twitter.png
deleted file mode 100644
index 3d1856f834..0000000000
Binary files a/lms/static/images_old/twitter.png and /dev/null differ
diff --git a/lms/static/images_old/ui-bg_flat_0_aaaaaa_40x100.png b/lms/static/images_old/ui-bg_flat_0_aaaaaa_40x100.png
deleted file mode 100644
index 5b5dab2ab7..0000000000
Binary files a/lms/static/images_old/ui-bg_flat_0_aaaaaa_40x100.png and /dev/null differ
diff --git a/lms/static/images_old/ui-bg_flat_0_eeeeee_40x100.png b/lms/static/images_old/ui-bg_flat_0_eeeeee_40x100.png
deleted file mode 100644
index e44f861be1..0000000000
Binary files a/lms/static/images_old/ui-bg_flat_0_eeeeee_40x100.png and /dev/null differ
diff --git a/lms/static/images_old/ui-bg_flat_55_ffffff_40x100.png b/lms/static/images_old/ui-bg_flat_55_ffffff_40x100.png
deleted file mode 100644
index ac8b229af9..0000000000
Binary files a/lms/static/images_old/ui-bg_flat_55_ffffff_40x100.png and /dev/null differ
diff --git a/lms/static/images_old/ui-bg_flat_75_ffffff_40x100.png b/lms/static/images_old/ui-bg_flat_75_ffffff_40x100.png
deleted file mode 100644
index ac8b229af9..0000000000
Binary files a/lms/static/images_old/ui-bg_flat_75_ffffff_40x100.png and /dev/null differ
diff --git a/lms/static/images_old/ui-bg_glass_65_023063_1x400.png b/lms/static/images_old/ui-bg_glass_65_023063_1x400.png
deleted file mode 100644
index 644a1f78e3..0000000000
Binary files a/lms/static/images_old/ui-bg_glass_65_023063_1x400.png and /dev/null differ
diff --git a/lms/static/images_old/ui-bg_highlight-soft_100_7fbcdf_1x100.png b/lms/static/images_old/ui-bg_highlight-soft_100_7fbcdf_1x100.png
deleted file mode 100644
index 6c372415be..0000000000
Binary files a/lms/static/images_old/ui-bg_highlight-soft_100_7fbcdf_1x100.png and /dev/null differ
diff --git a/lms/static/images_old/ui-bg_highlight-soft_100_bddeff_1x100.png b/lms/static/images_old/ui-bg_highlight-soft_100_bddeff_1x100.png
deleted file mode 100644
index 2f6196c9b3..0000000000
Binary files a/lms/static/images_old/ui-bg_highlight-soft_100_bddeff_1x100.png and /dev/null differ
diff --git a/lms/static/images_old/ui-bg_highlight-soft_100_f6f6f6_1x100.png b/lms/static/images_old/ui-bg_highlight-soft_100_f6f6f6_1x100.png
deleted file mode 100644
index 5dcfaa9a01..0000000000
Binary files a/lms/static/images_old/ui-bg_highlight-soft_100_f6f6f6_1x100.png and /dev/null differ
diff --git a/lms/static/images_old/ui-bg_highlight-soft_25_7fbcdf_1x100.png b/lms/static/images_old/ui-bg_highlight-soft_25_7fbcdf_1x100.png
deleted file mode 100644
index 994b7557c4..0000000000
Binary files a/lms/static/images_old/ui-bg_highlight-soft_25_7fbcdf_1x100.png and /dev/null differ
diff --git a/lms/static/images_old/ui-bg_highlight-soft_25_bddeff_1x100.png b/lms/static/images_old/ui-bg_highlight-soft_25_bddeff_1x100.png
deleted file mode 100644
index 77f2cf7bc2..0000000000
Binary files a/lms/static/images_old/ui-bg_highlight-soft_25_bddeff_1x100.png and /dev/null differ
diff --git a/lms/static/images_old/ui-bg_highlight-soft_50_7fbcfd_1x100.png b/lms/static/images_old/ui-bg_highlight-soft_50_7fbcfd_1x100.png
deleted file mode 100644
index 6f70ca4003..0000000000
Binary files a/lms/static/images_old/ui-bg_highlight-soft_50_7fbcfd_1x100.png and /dev/null differ
diff --git a/lms/static/images_old/ui-icons_031634_256x240.png b/lms/static/images_old/ui-icons_031634_256x240.png
deleted file mode 100644
index 09c70d6470..0000000000
Binary files a/lms/static/images_old/ui-icons_031634_256x240.png and /dev/null differ
diff --git a/lms/static/images_old/ui-icons_adcc80_256x240.png b/lms/static/images_old/ui-icons_adcc80_256x240.png
deleted file mode 100644
index 370191a5ea..0000000000
Binary files a/lms/static/images_old/ui-icons_adcc80_256x240.png and /dev/null differ
diff --git a/lms/static/images_old/unanswered-icon.png b/lms/static/images_old/unanswered-icon.png
deleted file mode 100644
index 8ea9669b8c..0000000000
Binary files a/lms/static/images_old/unanswered-icon.png and /dev/null differ
diff --git a/lms/static/images_old/vcr.png b/lms/static/images_old/vcr.png
deleted file mode 100644
index aa2ac99e47..0000000000
Binary files a/lms/static/images_old/vcr.png and /dev/null differ
diff --git a/lms/static/images_old/video-image.png b/lms/static/images_old/video-image.png
deleted file mode 100644
index 379403a4c5..0000000000
Binary files a/lms/static/images_old/video-image.png and /dev/null differ
diff --git a/lms/static/js/jquery-ui.min.js b/lms/static/js/jquery-ui.min.js
deleted file mode 100755
index 3fe9ccb7b7..0000000000
--- a/lms/static/js/jquery-ui.min.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.core.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){function c(b,c){var e=b.nodeName.toLowerCase();if("area"===e){var f=b.parentNode,g=f.name,h;return!b.href||!g||f.nodeName.toLowerCase()!=="map"?!1:(h=a("img[usemap=#"+g+"]")[0],!!h&&d(h))}return(/input|select|textarea|button|object/.test(e)?!b.disabled:"a"==e?b.href||c:c)&&d(b)}function d(b){return!a(b).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.ui=a.ui||{};if(a.ui.version)return;a.extend(a.ui,{version:"1.8.21",keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,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,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}}),a.fn.extend({propAttr:a.fn.prop||a.fn.attr,_focus:a.fn.focus,focus:function(b,c){return typeof b=="number"?this.each(function(){var d=this;setTimeout(function(){a(d).focus(),c&&c.call(d)},b)}):this._focus.apply(this,arguments)},scrollParent:function(){var b;return a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?b=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):b=this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0),/fixed/.test(this.css("position"))||!b.length?a(document):b},zIndex:function(c){if(c!==b)return this.css("zIndex",c);if(this.length){var d=a(this[0]),e,f;while(d.length&&d[0]!==document){e=d.css("position");if(e==="absolute"||e==="relative"||e==="fixed"){f=parseInt(d.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}d=d.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),a.each(["Width","Height"],function(c,d){function h(b,c,d,f){return a.each(e,function(){c-=parseFloat(a.curCSS(b,"padding"+this,!0))||0,d&&(c-=parseFloat(a.curCSS(b,"border"+this+"Width",!0))||0),f&&(c-=parseFloat(a.curCSS(b,"margin"+this,!0))||0)}),c}var e=d==="Width"?["Left","Right"]:["Top","Bottom"],f=d.toLowerCase(),g={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth,outerHeight:a.fn.outerHeight};a.fn["inner"+d]=function(c){return c===b?g["inner"+d].call(this):this.each(function(){a(this).css(f,h(this,c)+"px")})},a.fn["outer"+d]=function(b,c){return typeof b!="number"?g["outer"+d].call(this,b):this.each(function(){a(this).css(f,h(this,b,!0,c)+"px")})}}),a.extend(a.expr[":"],{data:function(b,c,d){return!!a.data(b,d[3])},focusable:function(b){return c(b,!isNaN(a.attr(b,"tabindex")))},tabbable:function(b){var d=a.attr(b,"tabindex"),e=isNaN(d);return(e||d>=0)&&c(b,!e)}}),a(function(){var b=document.body,c=b.appendChild(c=document.createElement("div"));c.offsetHeight,a.extend(c.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),a.support.minHeight=c.offsetHeight===100,a.support.selectstart="onselectstart"in c,b.removeChild(c).style.display="none"}),a.extend(a.ui,{plugin:{add:function(b,c,d){var e=a.ui[b].prototype;for(var f in d)e.plugins[f]=e.plugins[f]||[],e.plugins[f].push([c,d[f]])},call:function(a,b,c){var d=a.plugins[b];if(!d||!a.element[0].parentNode)return;for(var e=0;e0?!0:(b[d]=1,e=b[d]>0,b[d]=0,e)},isOverAxis:function(a,b,c){return a>b&&a=9||!!b.button?this._mouseStarted?(this._mouseDrag(b),b.preventDefault()):(this._mouseDistanceMet(b)&&this._mouseDelayMet(b)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,b)!==!1,this._mouseStarted?this._mouseDrag(b):this._mouseUp(b)),!this._mouseStarted):this._mouseUp(b)},_mouseUp:function(b){return a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,b.target==this._mouseDownEvent.target&&a.data(b.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(b)),!1},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(a){return this.mouseDelayMet},_mouseStart:function(a){},_mouseDrag:function(a){},_mouseStop:function(a){},_mouseCapture:function(a){return!0}})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.position.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.ui=a.ui||{};var c=/left|center|right/,d=/top|center|bottom/,e="center",f={},g=a.fn.position,h=a.fn.offset;a.fn.position=function(b){if(!b||!b.of)return g.apply(this,arguments);b=a.extend({},b);var h=a(b.of),i=h[0],j=(b.collision||"flip").split(" "),k=b.offset?b.offset.split(" "):[0,0],l,m,n;return i.nodeType===9?(l=h.width(),m=h.height(),n={top:0,left:0}):i.setTimeout?(l=h.width(),m=h.height(),n={top:h.scrollTop(),left:h.scrollLeft()}):i.preventDefault?(b.at="left top",l=m=0,n={top:b.of.pageY,left:b.of.pageX}):(l=h.outerWidth(),m=h.outerHeight(),n=h.offset()),a.each(["my","at"],function(){var a=(b[this]||"").split(" ");a.length===1&&(a=c.test(a[0])?a.concat([e]):d.test(a[0])?[e].concat(a):[e,e]),a[0]=c.test(a[0])?a[0]:e,a[1]=d.test(a[1])?a[1]:e,b[this]=a}),j.length===1&&(j[1]=j[0]),k[0]=parseInt(k[0],10)||0,k.length===1&&(k[1]=k[0]),k[1]=parseInt(k[1],10)||0,b.at[0]==="right"?n.left+=l:b.at[0]===e&&(n.left+=l/2),b.at[1]==="bottom"?n.top+=m:b.at[1]===e&&(n.top+=m/2),n.left+=k[0],n.top+=k[1],this.each(function(){var c=a(this),d=c.outerWidth(),g=c.outerHeight(),h=parseInt(a.curCSS(this,"marginLeft",!0))||0,i=parseInt(a.curCSS(this,"marginTop",!0))||0,o=d+h+(parseInt(a.curCSS(this,"marginRight",!0))||0),p=g+i+(parseInt(a.curCSS(this,"marginBottom",!0))||0),q=a.extend({},n),r;b.my[0]==="right"?q.left-=d:b.my[0]===e&&(q.left-=d/2),b.my[1]==="bottom"?q.top-=g:b.my[1]===e&&(q.top-=g/2),f.fractions||(q.left=Math.round(q.left),q.top=Math.round(q.top)),r={left:q.left-h,top:q.top-i},a.each(["left","top"],function(c,e){a.ui.position[j[c]]&&a.ui.position[j[c]][e](q,{targetWidth:l,targetHeight:m,elemWidth:d,elemHeight:g,collisionPosition:r,collisionWidth:o,collisionHeight:p,offset:k,my:b.my,at:b.at})}),a.fn.bgiframe&&c.bgiframe(),c.offset(a.extend(q,{using:b.using}))})},a.ui.position={fit:{left:function(b,c){var d=a(window),e=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft();b.left=e>0?b.left-e:Math.max(b.left-c.collisionPosition.left,b.left)},top:function(b,c){var d=a(window),e=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop();b.top=e>0?b.top-e:Math.max(b.top-c.collisionPosition.top,b.top)}},flip:{left:function(b,c){if(c.at[0]===e)return;var d=a(window),f=c.collisionPosition.left+c.collisionWidth-d.width()-d.scrollLeft(),g=c.my[0]==="left"?-c.elemWidth:c.my[0]==="right"?c.elemWidth:0,h=c.at[0]==="left"?c.targetWidth:-c.targetWidth,i=-2*c.offset[0];b.left+=c.collisionPosition.left<0?g+h+i:f>0?g+h+i:0},top:function(b,c){if(c.at[1]===e)return;var d=a(window),f=c.collisionPosition.top+c.collisionHeight-d.height()-d.scrollTop(),g=c.my[1]==="top"?-c.elemHeight:c.my[1]==="bottom"?c.elemHeight:0,h=c.at[1]==="top"?c.targetHeight:-c.targetHeight,i=-2*c.offset[1];b.top+=c.collisionPosition.top<0?g+h+i:f>0?g+h+i:0}}},a.offset.setOffset||(a.offset.setOffset=function(b,c){/static/.test(a.curCSS(b,"position"))&&(b.style.position="relative");var d=a(b),e=d.offset(),f=parseInt(a.curCSS(b,"top",!0),10)||0,g=parseInt(a.curCSS(b,"left",!0),10)||0,h={top:c.top-e.top+f,left:c.left-e.left+g};"using"in c?c.using.call(b,h):d.css(h)},a.fn.offset=function(b){var c=this[0];return!c||!c.ownerDocument?null:b?a.isFunction(b)?this.each(function(c){a(this).offset(b.call(this,c,a(this).offset()))}):this.each(function(){a.offset.setOffset(this,b)}):h.call(this)}),function(){var b=document.getElementsByTagName("body")[0],c=document.createElement("div"),d,e,g,h,i;d=document.createElement(b?"div":"body"),g={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"},b&&a.extend(g,{position:"absolute",left:"-1000px",top:"-1000px"});for(var j in g)d.style[j]=g[j];d.appendChild(c),e=b||document.documentElement,e.insertBefore(d,e.firstChild),c.style.cssText="position: absolute; left: 10.7432222px; top: 10.432325px; height: 30px; width: 201px;",h=a(c).offset(function(a,b){return b}).offset(),d.innerHTML="",e.removeChild(d),i=h.top+h.left+(b?2e3:0),f.fractions=i>21&&i<22}()})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.draggable.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.widget("ui.draggable",a.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},destroy:function(){if(!this.element.data("draggable"))return;return this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy(),this},_mouseCapture:function(b){var c=this.options;return this.helper||c.disabled||a(b.target).is(".ui-resizable-handle")?!1:(this.handle=this._getHandle(b),this.handle?(c.iframeFix&&a(c.iframeFix===!0?"iframe":c.iframeFix).each(function(){a('').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(a(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(b){var c=this.options;return this.helper=this._createHelper(b),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),a.ui.ddmanager&&(a.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt),c.containment&&this._setContainment(),this._trigger("start",b)===!1?(this._clear(),!1):(this._cacheHelperProportions(),a.ui.ddmanager&&!c.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this._mouseDrag(b,!0),a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,b),!0)},_mouseDrag:function(b,c){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute");if(!c){var d=this._uiHash();if(this._trigger("drag",b,d)===!1)return this._mouseUp({}),!1;this.position=d.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";return a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),!1},_mouseStop:function(b){var c=!1;a.ui.ddmanager&&!this.options.dropBehaviour&&(c=a.ui.ddmanager.drop(this,b)),this.dropped&&(c=this.dropped,this.dropped=!1);var d=this.element[0],e=!1;while(d&&(d=d.parentNode))d==document&&(e=!0);if(!e&&this.options.helper==="original")return!1;if(this.options.revert=="invalid"&&!c||this.options.revert=="valid"&&c||this.options.revert===!0||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var f=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){f._trigger("stop",b)!==!1&&f._clear()})}else this._trigger("stop",b)!==!1&&this._clear();return!1},_mouseUp:function(b){return this.options.iframeFix===!0&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,b),a.ui.mouse.prototype._mouseUp.call(this,b)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?!0:!1;return a(this.options.handle,this.element).find("*").andSelf().each(function(){this==b.target&&(c=!0)}),c},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b])):c.helper=="clone"?this.element.clone().removeAttr("id"):this.element;return d.parents("body").length||d.appendTo(c.appendTo=="parent"?this.element[0].parentNode:c.appendTo),d[0]!=this.element[0]&&!/(fixed|absolute)/.test(d.css("position"))&&d.css("position","absolute"),d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[b.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,b.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(b.containment=="document"?0:a(window).scrollLeft())+a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(b.containment=="document"?0:a(window).scrollTop())+(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)&&b.containment.constructor!=Array){var c=a(b.containment),d=c[0];if(!d)return;var e=c.offset(),f=a(d).css("overflow")!="hidden";this.containment=[(parseInt(a(d).css("borderLeftWidth"),10)||0)+(parseInt(a(d).css("paddingLeft"),10)||0),(parseInt(a(d).css("borderTopWidth"),10)||0)+(parseInt(a(d).css("paddingTop"),10)||0),(f?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(a(d).css("borderLeftWidth"),10)||0)-(parseInt(a(d).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(f?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(a(d).css("borderTopWidth"),10)||0)-(parseInt(a(d).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=c}else b.containment.constructor==Array&&(this.containment=b.containment)},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName),f=b.pageX,g=b.pageY;if(this.originalPosition){var h;if(this.containment){if(this.relative_container){var i=this.relative_container.offset();h=[this.containment[0]+i.left,this.containment[1]+i.top,this.containment[2]+i.left,this.containment[3]+i.top]}else h=this.containment;b.pageX-this.offset.click.lefth[2]&&(f=h[2]+this.offset.click.left),b.pageY-this.offset.click.top>h[3]&&(g=h[3]+this.offset.click.top)}if(c.grid){var j=c.grid[1]?this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY;g=h?j-this.offset.click.toph[3]?j-this.offset.click.toph[2]?k-this.offset.click.left=0;k--){var l=d.snapElements[k].left,m=l+d.snapElements[k].width,n=d.snapElements[k].top,o=n+d.snapElements[k].height;if(!(l-f=k&&g<=l||h>=k&&h<=l||gl)&&(e>=i&&e<=j||f>=i&&f<=j||ej);default:return!1}},a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(b,c){var d=a.ui.ddmanager.droppables[b.options.scope]||[],e=c?c.type:null,f=(b.currentItem||b.element).find(":data(droppable)").andSelf();g:for(var h=0;h').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=c.handles||(a(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var d=this.handles.split(",");this.handles={};for(var e=0;e');h.css({zIndex:c.zIndex}),"se"==f&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[f]=".ui-resizable-"+f,this.element.append(h)}}this._renderAxis=function(b){b=b||this.element;for(var c in this.handles){this.handles[c].constructor==String&&(this.handles[c]=a(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var d=a(this.handles[c],this.element),e=0;e=/sw|ne|nw|se|n|s/.test(c)?d.outerHeight():d.outerWidth();var f=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");b.css(f,e),this._proportionallyResize()}if(!a(this.handles[c]).length)continue}},this._renderAxis(this.element),this._handles=a(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!b.resizing){if(this.className)var a=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=a&&a[1]?a[1]:"se"}}),c.autoHide&&(this._handles.hide(),a(this.element).addClass("ui-resizable-autohide").hover(function(){if(c.disabled)return;a(this).removeClass("ui-resizable-autohide"),b._handles.show()},function(){if(c.disabled)return;b.resizing||(a(this).addClass("ui-resizable-autohide"),b._handles.hide())})),this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(b){a(b).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var c=this.element;c.after(this.originalElement.css({position:c.css("position"),width:c.outerWidth(),height:c.outerHeight(),top:c.css("top"),left:c.css("left")})).remove()}return this.originalElement.css("resize",this.originalResizeStyle),b(this.originalElement),this},_mouseCapture:function(b){var c=!1;for(var d in this.handles)a(this.handles[d])[0]==b.target&&(c=!0);return!this.options.disabled&&c},_mouseStart:function(b){var d=this.options,e=this.element.position(),f=this.element;this.resizing=!0,this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()},(f.is(".ui-draggable")||/absolute/.test(f.css("position")))&&f.css({position:"absolute",top:e.top,left:e.left}),this._renderProxy();var g=c(this.helper.css("left")),h=c(this.helper.css("top"));d.containment&&(g+=a(d.containment).scrollLeft()||0,h+=a(d.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:g,top:h},this.size=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalSize=this._helper?{width:f.outerWidth(),height:f.outerHeight()}:{width:f.width(),height:f.height()},this.originalPosition={left:g,top:h},this.sizeDiff={width:f.outerWidth()-f.width(),height:f.outerHeight()-f.height()},this.originalMousePosition={left:b.pageX,top:b.pageY},this.aspectRatio=typeof d.aspectRatio=="number"?d.aspectRatio:this.originalSize.width/this.originalSize.height||1;var i=a(".ui-resizable-"+this.axis).css("cursor");return a("body").css("cursor",i=="auto"?this.axis+"-resize":i),f.addClass("ui-resizable-resizing"),this._propagate("start",b),!0},_mouseDrag:function(b){var c=this.helper,d=this.options,e={},f=this,g=this.originalMousePosition,h=this.axis,i=b.pageX-g.left||0,j=b.pageY-g.top||0,k=this._change[h];if(!k)return!1;var l=k.apply(this,[b,i,j]),m=a.browser.msie&&a.browser.version<7,n=this.sizeDiff;this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)l=this._updateRatio(l,b);return l=this._respectSize(l,b),this._propagate("resize",b),c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",b,this.ui()),!1},_mouseStop:function(b){this.resizing=!1;var c=this.options,d=this;if(this._helper){var e=this._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName),g=f&&a.ui.hasScroll(e[0],"left")?0:d.sizeDiff.height,h=f?0:d.sizeDiff.width,i={width:d.helper.width()-h,height:d.helper.height()-g},j=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,k=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;c.animate||this.element.css(a.extend(i,{top:k,left:j})),d.helper.height(d.size.height),d.helper.width(d.size.width),this._helper&&!c.animate&&this._proportionallyResize()}return a("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",b),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(a){var b=this.options,c,e,f,g,h;h={minWidth:d(b.minWidth)?b.minWidth:0,maxWidth:d(b.maxWidth)?b.maxWidth:Infinity,minHeight:d(b.minHeight)?b.minHeight:0,maxHeight:d(b.maxHeight)?b.maxHeight:Infinity};if(this._aspectRatio||a)c=h.minHeight*this.aspectRatio,f=h.minWidth/this.aspectRatio,e=h.maxHeight*this.aspectRatio,g=h.maxWidth/this.aspectRatio,c>h.minWidth&&(h.minWidth=c),f>h.minHeight&&(h.minHeight=f),ea.width,k=d(a.height)&&e.minHeight&&e.minHeight>a.height;j&&(a.width=e.minWidth),k&&(a.height=e.minHeight),h&&(a.width=e.maxWidth),i&&(a.height=e.maxHeight);var l=this.originalPosition.left+this.originalSize.width,m=this.position.top+this.size.height,n=/sw|nw|w/.test(g),o=/nw|ne|n/.test(g);j&&n&&(a.left=l-e.minWidth),h&&n&&(a.left=l-e.maxWidth),k&&o&&(a.top=m-e.minHeight),i&&o&&(a.top=m-e.maxHeight);var p=!a.width&&!a.height;return p&&!a.left&&a.top?a.top=null:p&&!a.top&&a.left&&(a.left=null),a},_proportionallyResize:function(){var b=this.options;if(!this._proportionallyResizeElements.length)return;var c=this.helper||this.element;for(var d=0;d');var d=a.browser.msie&&a.browser.version<7,e=d?1:0,f=d?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+f,height:this.element.outerHeight()+f,position:"absolute",left:this.elementOffset.left-e+"px",top:this.elementOffset.top-e+"px",zIndex:++c.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(a,b,c){return{width:this.originalSize.width+b}},w:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{left:f.left+b,width:e.width-b}},n:function(a,b,c){var d=this.options,e=this.originalSize,f=this.originalPosition;return{top:f.top+c,height:e.height-c}},s:function(a,b,c){return{height:this.originalSize.height+c}},se:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},sw:function(b,c,d){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,c,d]))},ne:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,c,d]))},nw:function(b,c,d){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,c,d]))}},_propagate:function(b,c){a.ui.plugin.call(this,b,[c,this.ui()]),b!="resize"&&this._trigger(b,c,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),a.extend(a.ui.resizable,{version:"1.8.21"}),a.ui.plugin.add("resizable","alsoResize",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=function(b){a(b).each(function(){var b=a(this);b.data("resizable-alsoresize",{width:parseInt(b.width(),10),height:parseInt(b.height(),10),left:parseInt(b.css("left"),10),top:parseInt(b.css("top"),10)})})};typeof e.alsoResize=="object"&&!e.alsoResize.parentNode?e.alsoResize.length?(e.alsoResize=e.alsoResize[0],f(e.alsoResize)):a.each(e.alsoResize,function(a){f(a)}):f(e.alsoResize)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.originalSize,g=d.originalPosition,h={height:d.size.height-f.height||0,width:d.size.width-f.width||0,top:d.position.top-g.top||0,left:d.position.left-g.left||0},i=function(b,d){a(b).each(function(){var b=a(this),e=a(this).data("resizable-alsoresize"),f={},g=d&&d.length?d:b.parents(c.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(g,function(a,b){var c=(e[b]||0)+(h[b]||0);c&&c>=0&&(f[b]=c||null)}),b.css(f)})};typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(a,b){i(a,b)}):i(e.alsoResize)},stop:function(b,c){a(this).removeData("resizable-alsoresize")}}),a.ui.plugin.add("resizable","animate",{stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d._proportionallyResizeElements,g=f.length&&/textarea/i.test(f[0].nodeName),h=g&&a.ui.hasScroll(f[0],"left")?0:d.sizeDiff.height,i=g?0:d.sizeDiff.width,j={width:d.size.width-i,height:d.size.height-h},k=parseInt(d.element.css("left"),10)+(d.position.left-d.originalPosition.left)||null,l=parseInt(d.element.css("top"),10)+(d.position.top-d.originalPosition.top)||null;d.element.animate(a.extend(j,l&&k?{top:l,left:k}:{}),{duration:e.animateDuration,easing:e.animateEasing,step:function(){var c={width:parseInt(d.element.css("width"),10),height:parseInt(d.element.css("height"),10),top:parseInt(d.element.css("top"),10),left:parseInt(d.element.css("left"),10)};f&&f.length&&a(f[0]).css({width:c.width,height:c.height}),d._updateCache(c),d._propagate("resize",b)}})}}),a.ui.plugin.add("resizable","containment",{start:function(b,d){var e=a(this).data("resizable"),f=e.options,g=e.element,h=f.containment,i=h instanceof a?h.get(0):/parent/.test(h)?g.parent().get(0):h;if(!i)return;e.containerElement=a(i);if(/document/.test(h)||h==document)e.containerOffset={left:0,top:0},e.containerPosition={left:0,top:0},e.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight};else{var j=a(i),k=[];a(["Top","Right","Left","Bottom"]).each(function(a,b){k[a]=c(j.css("padding"+b))}),e.containerOffset=j.offset(),e.containerPosition=j.position(),e.containerSize={height:j.innerHeight()-k[3],width:j.innerWidth()-k[1]};var l=e.containerOffset,m=e.containerSize.height,n=e.containerSize.width,o=a.ui.hasScroll(i,"left")?i.scrollWidth:n,p=a.ui.hasScroll(i)?i.scrollHeight:m;e.parentData={element:i,left:l.left,top:l.top,width:o,height:p}}},resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.containerSize,g=d.containerOffset,h=d.size,i=d.position,j=d._aspectRatio||b.shiftKey,k={top:0,left:0},l=d.containerElement;l[0]!=document&&/static/.test(l.css("position"))&&(k=g),i.left<(d._helper?g.left:0)&&(d.size.width=d.size.width+(d._helper?d.position.left-g.left:d.position.left-k.left),j&&(d.size.height=d.size.width/d.aspectRatio),d.position.left=e.helper?g.left:0),i.top<(d._helper?g.top:0)&&(d.size.height=d.size.height+(d._helper?d.position.top-g.top:d.position.top),j&&(d.size.width=d.size.height*d.aspectRatio),d.position.top=d._helper?g.top:0),d.offset.left=d.parentData.left+d.position.left,d.offset.top=d.parentData.top+d.position.top;var m=Math.abs((d._helper?d.offset.left-k.left:d.offset.left-k.left)+d.sizeDiff.width),n=Math.abs((d._helper?d.offset.top-k.top:d.offset.top-g.top)+d.sizeDiff.height),o=d.containerElement.get(0)==d.element.parent().get(0),p=/relative|absolute/.test(d.containerElement.css("position"));o&&p&&(m-=d.parentData.left),m+d.size.width>=d.parentData.width&&(d.size.width=d.parentData.width-m,j&&(d.size.height=d.size.width/d.aspectRatio)),n+d.size.height>=d.parentData.height&&(d.size.height=d.parentData.height-n,j&&(d.size.width=d.size.height*d.aspectRatio))},stop:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.position,g=d.containerOffset,h=d.containerPosition,i=d.containerElement,j=a(d.helper),k=j.offset(),l=j.outerWidth()-d.sizeDiff.width,m=j.outerHeight()-d.sizeDiff.height;d._helper&&!e.animate&&/relative/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m}),d._helper&&!e.animate&&/static/.test(i.css("position"))&&a(this).css({left:k.left-h.left-g.left,width:l,height:m})}}),a.ui.plugin.add("resizable","ghost",{start:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size;d.ghost=d.originalElement.clone(),d.ghost.css({opacity:.25,display:"block",position:"relative",height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:""),d.ghost.appendTo(d.helper)},resize:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})},stop:function(b,c){var d=a(this).data("resizable"),e=d.options;d.ghost&&d.helper&&d.helper.get(0).removeChild(d.ghost.get(0))}}),a.ui.plugin.add("resizable","grid",{resize:function(b,c){var d=a(this).data("resizable"),e=d.options,f=d.size,g=d.originalSize,h=d.originalPosition,i=d.axis,j=e._aspectRatio||b.shiftKey;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-g.width)/(e.grid[0]||1))*(e.grid[0]||1),l=Math.round((f.height-g.height)/(e.grid[1]||1))*(e.grid[1]||1);/^(se|s|e)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l):/^(ne)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l):/^(sw)$/.test(i)?(d.size.width=g.width+k,d.size.height=g.height+l,d.position.left=h.left-k):(d.size.width=g.width+k,d.size.height=g.height+l,d.position.top=h.top-l,d.position.left=h.left-k)}});var c=function(a){return parseInt(a,10)||0},d=function(a){return!isNaN(parseInt(a,10))}})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.selectable.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){a.widget("ui.selectable",a.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var b=this;this.element.addClass("ui-selectable"),this.dragged=!1;var c;this.refresh=function(){c=a(b.options.filter,b.element[0]),c.addClass("ui-selectee"),c.each(function(){var b=a(this),c=b.offset();a.data(this,"selectable-item",{element:this,$element:b,left:c.left,top:c.top,right:c.left+b.outerWidth(),bottom:c.top+b.outerHeight(),startselected:!1,selected:b.hasClass("ui-selected"),selecting:b.hasClass("ui-selecting"),unselecting:b.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=c.addClass("ui-selectee"),this._mouseInit(),this.helper=a("")},destroy:function(){return this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable"),this._mouseDestroy(),this},_mouseStart:function(b){var c=this;this.opos=[b.pageX,b.pageY];if(this.options.disabled)return;var d=this.options;this.selectees=a(d.filter,this.element[0]),this._trigger("start",b),a(d.appendTo).append(this.helper),this.helper.css({left:b.clientX,top:b.clientY,width:0,height:0}),d.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var d=a.data(this,"selectable-item");d.startselected=!0,!b.metaKey&&!b.ctrlKey&&(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",b,{unselecting:d.element}))}),a(b.target).parents().andSelf().each(function(){var d=a.data(this,"selectable-item");if(d){var e=!b.metaKey&&!b.ctrlKey||!d.$element.hasClass("ui-selected");return d.$element.removeClass(e?"ui-unselecting":"ui-selected").addClass(e?"ui-selecting":"ui-unselecting"),d.unselecting=!e,d.selecting=e,d.selected=e,e?c._trigger("selecting",b,{selecting:d.element}):c._trigger("unselecting",b,{unselecting:d.element}),!1}})},_mouseDrag:function(b){var c=this;this.dragged=!0;if(this.options.disabled)return;var d=this.options,e=this.opos[0],f=this.opos[1],g=b.pageX,h=b.pageY;if(e>g){var i=g;g=e,e=i}if(f>h){var i=h;h=f,f=i}return this.helper.css({left:e,top:f,width:g-e,height:h-f}),this.selectees.each(function(){var i=a.data(this,"selectable-item");if(!i||i.element==c.element[0])return;var j=!1;d.tolerance=="touch"?j=!(i.left>g||i.righth||i.bottome&&i.rightf&&i.bottom *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var a=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},destroy:function(){a.Widget.prototype.destroy.call(this),this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var b=this.items.length-1;b>=0;b--)this.items[b].item.removeData(this.widgetName+"-item");return this},_setOption:function(b,c){b==="disabled"?(this.options[b]=c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(b,c){var d=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(b);var e=null,f=this,g=a(b.target).parents().each(function(){if(a.data(this,d.widgetName+"-item")==f)return e=a(this),!1});a.data(b.target,d.widgetName+"-item")==f&&(e=a(b.target));if(!e)return!1;if(this.options.handle&&!c){var h=!1;a(this.options.handle,e).find("*").andSelf().each(function(){this==b.target&&(h=!0)});if(!h)return!1}return this.currentItem=e,this._removeCurrentsFromItems(),!0},_mouseStart:function(b,c,d){var e=this.options,f=this;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(b),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},a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.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(b),this.originalPageX=b.pageX,this.originalPageY=b.pageY,e.cursorAt&&this._adjustOffsetFromHelper(e.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),e.containment&&this._setContainment(),e.cursor&&(a("body").css("cursor")&&(this._storedCursor=a("body").css("cursor")),a("body").css("cursor",e.cursor)),e.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",e.opacity)),e.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",e.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",b,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(var g=this.containers.length-1;g>=0;g--)this.containers[g]._trigger("activate",b,f._uiHash(this));return a.ui.ddmanager&&(a.ui.ddmanager.current=this),a.ui.ddmanager&&!e.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,b),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(b),!0},_mouseDrag:function(b){this.position=this._generatePosition(b),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-b.pageY=0;e--){var f=this.items[e],g=f.item[0],h=this._intersectsWithPointer(f);if(!h)continue;if(g!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=g&&!a.ui.contains(this.placeholder[0],g)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],g):!0)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(f))this._rearrange(b,f);else break;this._trigger("change",b,this._uiHash());break}}return this._contactContainers(b),a.ui.ddmanager&&a.ui.ddmanager.drag(this,b),this._trigger("sort",b,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(b,c){if(!b)return;a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,b);if(this.options.revert){var d=this,e=d.placeholder.offset();d.reverting=!0,a(this.helper).animate({left:e.left-this.offset.parent.left-d.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-d.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){d._clear(b)})}else this._clear(b,c);return!1},cancel:function(){var b=this;if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("deactivate",null,b._uiHash(this)),this.containers[c].containerCache.over&&(this.containers[c]._trigger("out",null,b._uiHash(this)),this.containers[c].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),a.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},a(c).each(function(){var c=(a(b.item||this).attr(b.attribute||"id")||"").match(b.expression||/(.+)[-=_](.+)/);c&&d.push((b.key||c[1]+"[]")+"="+(b.key&&b.expression?c[1]:c[2]))}),!d.length&&b.key&&d.push(b.key+"="),d.join("&")},toArray:function(b){var c=this._getItemsAsjQuery(b&&b.connected),d=[];return b=b||{},c.each(function(){d.push(a(b.item||this).attr(b.attribute||"id")||"")}),d},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,d=this.positionAbs.top,e=d+this.helperProportions.height,f=a.left,g=f+a.width,h=a.top,i=h+a.height,j=this.offset.click.top,k=this.offset.click.left,l=d+j>h&&d+jf&&b+ka[this.floating?"width":"height"]?l:f0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){return this._refreshItems(a),this.refreshPositions(),this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(b){var c=this,d=[],e=[],f=this._connectWith();if(f&&b)for(var g=f.length-1;g>=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&e.push([a.isFunction(j.options.items)?j.options.items.call(j.element):a(j.options.items,j.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),j])}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var g=e.length-1;g>=0;g--)e[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){var a=this.currentItem.find(":data("+this.widgetName+"-item)");for(var b=0;b=0;g--){var h=a(f[g]);for(var i=h.length-1;i>=0;i--){var j=a.data(h[i],this.widgetName);j&&j!=this&&!j.options.disabled&&(e.push([a.isFunction(j.options.items)?j.options.items.call(j.element[0],b,{item:this.currentItem}):a(j.options.items,j.element),j]),this.containers.push(j))}}for(var g=e.length-1;g>=0;g--){var k=e[g][1],l=e[g][0];for(var i=0,m=l.length;i=0;c--){var d=this.items[c];if(d.instance!=this.currentContainer&&this.currentContainer&&d.item[0]!=this.currentItem[0])continue;var e=this.options.toleranceElement?a(this.options.toleranceElement,d.item):d.item;b||(d.width=e.outerWidth(),d.height=e.outerHeight());var f=e.offset();d.left=f.left,d.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var c=this.containers.length-1;c>=0;c--){var f=this.containers[c].element.offset();this.containers[c].containerCache.left=f.left,this.containers[c].containerCache.top=f.top,this.containers[c].containerCache.width=this.containers[c].element.outerWidth(),this.containers[c].containerCache.height=this.containers[c].element.outerHeight()}return this},_createPlaceholder:function(b){var c=b||this,d=c.options;if(!d.placeholder||d.placeholder.constructor==String){var e=d.placeholder;d.placeholder={element:function(){var b=a(document.createElement(c.currentItem[0].nodeName)).addClass(e||c.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return e||(b.style.visibility="hidden"),b},update:function(a,b){if(e&&!d.forcePlaceholderSize)return;b.height()||b.height(c.currentItem.innerHeight()-parseInt(c.currentItem.css("paddingTop")||0,10)-parseInt(c.currentItem.css("paddingBottom")||0,10)),b.width()||b.width(c.currentItem.innerWidth()-parseInt(c.currentItem.css("paddingLeft")||0,10)-parseInt(c.currentItem.css("paddingRight")||0,10))}}}c.placeholder=a(d.placeholder.element.call(c.element,c.currentItem)),c.currentItem.after(c.placeholder),d.placeholder.update(c,c.placeholder)},_contactContainers:function(b){var c=null,d=null;for(var e=this.containers.length-1;e>=0;e--){if(a.ui.contains(this.currentItem[0],this.containers[e].element[0]))continue;if(this._intersectsWith(this.containers[e].containerCache)){if(c&&a.ui.contains(this.containers[e].element[0],c.element[0]))continue;c=this.containers[e],d=e}else this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",b,this._uiHash(this)),this.containers[e].containerCache.over=0)}if(!c)return;if(this.containers.length===1)this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1;else if(this.currentContainer!=this.containers[d]){var f=1e4,g=null,h=this.positionAbs[this.containers[d].floating?"left":"top"];for(var i=this.items.length-1;i>=0;i--){if(!a.ui.contains(this.containers[d].element[0],this.items[i].item[0]))continue;var j=this.containers[d].floating?this.items[i].item.offset().left:this.items[i].item.offset().top;Math.abs(j-h)0?"down":"up")}if(!g&&!this.options.dropOnEmpty)return;this.currentContainer=this.containers[d],g?this._rearrange(b,g,null,!0):this._rearrange(b,null,this.containers[d].element,!0),this._trigger("change",b,this._uiHash()),this.containers[d]._trigger("change",b,this._uiHash(this)),this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[d]._trigger("over",b,this._uiHash(this)),this.containers[d].containerCache.over=1}},_createHelper:function(b){var c=this.options,d=a.isFunction(c.helper)?a(c.helper.apply(this.element[0],[b,this.currentItem])):c.helper=="clone"?this.currentItem.clone():this.currentItem;return d.parents("body").length||a(c.appendTo!="parent"?c.appendTo:this.currentItem[0].parentNode)[0].appendChild(d[0]),d[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")}),(d[0].style.width==""||c.forceHelperSize)&&d.width(this.currentItem.width()),(d[0].style.height==""||c.forceHelperSize)&&d.height(this.currentItem.height()),d},_adjustOffsetFromHelper:function(b){typeof b=="string"&&(b=b.split(" ")),a.isArray(b)&&(b={left:+b[0],top:+b[1]||0}),"left"in b&&(this.offset.click.left=b.left+this.margins.left),"right"in b&&(this.offset.click.left=this.helperProportions.width-b.right+this.margins.left),"top"in b&&(this.offset.click.top=b.top+this.margins.top),"bottom"in b&&(this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])&&(b.left+=this.scrollParent.scrollLeft(),b.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)b={top:0,left:0};return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.currentItem.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.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 b=this.options;b.containment=="parent"&&(b.containment=this.helper[0].parentNode);if(b.containment=="document"||b.containment=="window")this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(b.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(b.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(b.containment)){var c=a(b.containment)[0],d=a(b.containment).offset(),e=a(c).css("overflow")!="hidden";this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(e?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(e?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}},_convertPositionTo:function(b,c){c||(c=this.position);var d=b=="absolute"?1:-1,e=this.options,f=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=/(html|body)/i.test(f[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():g?0:f.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:f.scrollLeft())*d)}},_generatePosition:function(b){var c=this.options,d=this.cssPosition=="absolute"&&(this.scrollParent[0]==document||!a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(d[0].tagName);this.cssPosition=="relative"&&(this.scrollParent[0]==document||this.scrollParent[0]==this.offsetParent[0])&&(this.offset.relative=this._getRelativeOffset());var f=b.pageX,g=b.pageY;if(this.originalPosition){this.containment&&(b.pageX-this.offset.click.leftthis.containment[2]&&(f=this.containment[2]+this.offset.click.left),b.pageY-this.offset.click.top>this.containment[3]&&(g=this.containment[3]+this.offset.click.top));if(c.grid){var h=this.originalPageY+Math.round((g-this.originalPageY)/c.grid[1])*c.grid[1];g=this.containment?h-this.offset.click.topthis.containment[3]?h-this.offset.click.topthis.containment[2]?i-this.offset.click.left=0;f--)a.ui.contains(this.containers[f].element[0],this.currentItem[0])&&!c&&(d.push(function(a){return function(b){a._trigger("receive",b,this._uiHash(this))}}.call(this,this.containers[f])),d.push(function(a){return function(b){a._trigger("update",b,this._uiHash(this))}}.call(this,this.containers[f])))}for(var f=this.containers.length-1;f>=0;f--)c||d.push(function(a){return function(b){a._trigger("deactivate",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over&&(d.push(function(a){return function(b){a._trigger("out",b,this._uiHash(this))}}.call(this,this.containers[f])),this.containers[f].containerCache.over=0);this._storedCursor&&a("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!c){this._trigger("beforeStop",b,this._uiHash());for(var f=0;f li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var b=this,c=b.options;b.running=0,b.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"),b.headers=b.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){if(c.disabled)return;a(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){if(c.disabled)return;a(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){if(c.disabled)return;a(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){if(c.disabled)return;a(this).removeClass("ui-state-focus")}),b.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");if(c.navigation){var d=b.element.find("a").filter(c.navigationFilter).eq(0);if(d.length){var e=d.closest(".ui-accordion-header");e.length?b.active=e:b.active=d.closest(".ui-accordion-content").prev()}}b.active=b._findActive(b.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top"),b.active.next().addClass("ui-accordion-content-active"),b._createIcons(),b.resize(),b.element.attr("role","tablist"),b.headers.attr("role","tab").bind("keydown.accordion",function(a){return b._keydown(a)}).next().attr("role","tabpanel"),b.headers.not(b.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide(),b.active.length?b.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):b.headers.eq(0).attr("tabIndex",0),a.browser.safari||b.headers.find("a").attr("tabIndex",-1),c.event&&b.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(a){b._clickHandler.call(b,a,this),a.preventDefault()})},_createIcons:function(){var b=this.options;b.icons&&(a("").addClass("ui-icon "+b.icons.header).prependTo(this.headers),this.active.children(".ui-icon").toggleClass(b.icons.header).toggleClass(b.icons.headerSelected),this.element.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.children(".ui-icon").remove(),this.element.removeClass("ui-accordion-icons")},destroy:function(){var b=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"),this.headers.find("a").removeAttr("tabIndex"),this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");return(b.autoHeight||b.fillHeight)&&c.css("height",""),a.Widget.prototype.destroy.call(this)},_setOption:function(b,c){a.Widget.prototype._setOption.apply(this,arguments),b=="active"&&this.activate(c),b=="icons"&&(this._destroyIcons(),c&&this._createIcons()),b=="disabled"&&this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(b){if(this.options.disabled||b.altKey||b.ctrlKey)return;var c=a.ui.keyCode,d=this.headers.length,e=this.headers.index(b.target),f=!1;switch(b.keyCode){case c.RIGHT:case c.DOWN:f=this.headers[(e+1)%d];break;case c.LEFT:case c.UP:f=this.headers[(e-1+d)%d];break;case c.SPACE:case c.ENTER:this._clickHandler({target:b.target},b.target),b.preventDefault()}return f?(a(b.target).attr("tabIndex",-1),a(f).attr("tabIndex",0),f.focus(),!1):!0},resize:function(){var b=this.options,c;if(b.fillSpace){if(a.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height(),a.browser.msie&&this.element.parent().css("overflow",d),this.headers.each(function(){c-=a(this).outerHeight(!0)}),this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")}else b.autoHeight&&(c=0,this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c));return this},activate:function(a){this.options.active=a;var b=this._findActive(a)[0];return this._clickHandler({target:b},b),this},_findActive:function(b){return b?typeof b=="number"?this.headers.filter(":eq("+b+")"):this.headers.not(this.headers.not(b)):b===!1?a([]):this.headers.filter(":eq(0)")},_clickHandler:function(b,c){var d=this.options;if(d.disabled)return;if(!b.target){if(!d.collapsible)return;this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),this.active.next().addClass("ui-accordion-content-active");var e=this.active.next(),f={options:d,newHeader:a([]),oldHeader:d.active,newContent:a([]),oldContent:e},g=this.active=a([]);this._toggle(g,e,f);return}var h=a(b.currentTarget||c),i=h[0]===this.active[0];d.active=d.collapsible&&i?!1:this.headers.index(h);if(this.running||!d.collapsible&&i)return;var j=this.active,g=h.next(),e=this.active.next(),f={options:d,newHeader:i&&d.collapsible?a([]):h,oldHeader:this.active,newContent:i&&d.collapsible?a([]):g,oldContent:e},k=this.headers.index(this.active[0])>this.headers.index(h[0]);this.active=i?a([]):h,this._toggle(g,e,f,i,k),j.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header),i||(h.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected),h.next().addClass("ui-accordion-content-active"));return},_toggle:function(b,c,d,e,f){var g=this,h=g.options;g.toShow=b,g.toHide=c,g.data=d;var i=function(){if(!g)return;return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data),g.running=c.size()===0?b.size():c.size();if(h.animated){var j={};h.collapsible&&e?j={toShow:a([]),toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace}:j={toShow:b,toHide:c,complete:i,down:f,autoHeight:h.autoHeight||h.fillSpace},h.proxied||(h.proxied=h.animated),h.proxiedDuration||(h.proxiedDuration=h.duration),h.animated=a.isFunction(h.proxied)?h.proxied(j):h.proxied,h.duration=a.isFunction(h.proxiedDuration)?h.proxiedDuration(j):h.proxiedDuration;var k=a.ui.accordion.animations,l=h.duration,m=h.animated;m&&!k[m]&&!a.easing[m]&&(m="slide"),k[m]||(k[m]=function(a){this.slide(a,{easing:m,duration:l||700})}),k[m](j)}else h.collapsible&&e?b.toggle():(c.hide(),b.show()),i(!0);c.prev().attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).blur(),b.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(this.running)return;this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data)}}),a.extend(a.ui.accordion,{version:"1.8.21",animations:{slide:function(b,c){b=a.extend({easing:"swing",duration:300},b,c);if(!b.toHide.size()){b.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},b);return}if(!b.toShow.size()){b.toHide.animate({height:"hide",paddingTop:"hide",paddingBottom:"hide"},b);return}var d=b.toShow.css("overflow"),e=0,f={},g={},h=["height","paddingTop","paddingBottom"],i,j=b.toShow;i=j[0].style.width,j.width(j.parent().width()-parseFloat(j.css("paddingLeft"))-parseFloat(j.css("paddingRight"))-(parseFloat(j.css("borderLeftWidth"))||0)-(parseFloat(j.css("borderRightWidth"))||0)),a.each(h,function(c,d){g[d]="hide";var e=(""+a.css(b.toShow[0],d)).match(/^([\d+-.]+)(.*)$/);f[d]={value:e[1],unit:e[2]||"px"}}),b.toShow.css({height:0,overflow:"hidden"}).show(),b.toHide.filter(":hidden").each(b.complete).end().filter(":visible").animate(g,{step:function(a,c){c.prop=="height"&&(e=c.end-c.start===0?0:(c.now-c.start)/(c.end-c.start)),b.toShow[0].style[c.prop]=e*f[c.prop].value+f[c.prop].unit},duration:b.duration,easing:b.easing,complete:function(){b.autoHeight||b.toShow.css("height",""),b.toShow.css({width:i,overflow:d}),b.complete()}})},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1e3:200})}}})})(jQuery);;/*! jQuery UI - v1.8.21 - 2012-06-05
-* https://github.com/jquery/jquery-ui
-* Includes: jquery.ui.autocomplete.js
-* Copyright (c) 2012 AUTHORS.txt; Licensed MIT, GPL */
-(function(a,b){var c=0;a.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var b=this,c=this.element[0].ownerDocument,d;this.isMultiLine=this.element.is("textarea"),this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(b.options.disabled||b.element.propAttr("readOnly"))return;d=!1;var e=a.ui.keyCode;switch(c.keyCode){case e.PAGE_UP:b._move("previousPage",c);break;case e.PAGE_DOWN:b._move("nextPage",c);break;case e.UP:b._keyEvent("previous",c);break;case e.DOWN:b._keyEvent("next",c);break;case e.ENTER:case e.NUMPAD_ENTER:b.menu.active&&(d=!0,c.preventDefault());case e.TAB:if(!b.menu.active)return;b.menu.select(c);break;case e.ESCAPE:b.element.val(b.term),b.close(c);break;default:clearTimeout(b.searching),b.searching=setTimeout(function(){b.term!=b.element.val()&&(b.selectedItem=null,b.search(null,c))},b.options.delay)}}).bind("keypress.autocomplete",function(a){d&&(d=!1,a.preventDefault())}).bind("focus.autocomplete",function(){if(b.options.disabled)return;b.selectedItem=null,b.previous=b.element.val()}).bind("blur.autocomplete",function(a){if(b.options.disabled)return;clearTimeout(b.searching),b.closing=setTimeout(function(){b.close(a),b._change(a)},150)}),this._initSource(),this.menu=a("
What will UC Berkeley's direct participation entail?
UC Berkeley will begin by offering two courses on edX in Fall 2012, and will collaborate on the development of the technology platform. We will explore, experiment and innovate together.
+
UC Berkeley will also serve as the inaugural chair of the "X University" Consortium for an initial 5 year period. As Chair, UC Berkeley will participate on the edX Board on behalf of the X Universities.