galaxy-commits
Threads by month
- ----- 2026 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- 15302 discussions
commit/galaxy-central: greg: Dict url entry changes and improved logging for the Tool Shed api.
by commits-noreply@bitbucket.org 17 Jan '14
by commits-noreply@bitbucket.org 17 Jan '14
17 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/03f186a98017/
Changeset: 03f186a98017
User: greg
Date: 2014-01-17 22:35:05
Summary: Dict url entry changes and improved logging for the Tool Shed api.
Affected #: 1 file
diff -r 8704a185d43ef02b0dd763a89a9b003df0326d90 -r 03f186a9801738c9cab95275038851ed95922a49 lib/galaxy/webapps/tool_shed/api/repository_revisions.py
--- a/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
+++ b/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
@@ -186,9 +186,9 @@
value_mapper=self.__get_value_mapper( trans ) )
# We have to add the changeset_revision of of the repository dependency.
repository_dependency_dict[ 'changeset_revision' ] = changeset_revision
- repository_dependency_dict[ 'url' ] = web.url_for( controller='repository_revisions',
+ repository_dependency_dict[ 'url' ] = web.url_for( controller='repositories',
action='show',
- id=repository_dependency_repository_metadata_id )
+ id=repository_dependency_id )
repository_dependencies_dicts.append( repository_dependency_dict )
return repository_dependencies_dicts
@@ -205,11 +205,13 @@
if repository_metadata is None:
log.debug( 'Cannot locate repository_metadata with id %s' % str( id ) )
return {}
+ encoded_repository_id = trans.security.encode_id( repository_metadata.repository_id )
+ repository = suc.get_repository_by_id( trans, encoded_repository_id )
repository_metadata_dict = repository_metadata.to_dict( view='element',
value_mapper=self.__get_value_mapper( trans ) )
- repository_metadata_dict[ 'url' ] = web.url_for( controller='repository_revisions',
+ repository_metadata_dict[ 'url' ] = web.url_for( controller='repositories',
action='show',
- id=trans.security.encode_id( repository_metadata.id ) )
+ id=encoded_repository_id )
return repository_metadata_dict
@web.expose_api
@@ -223,8 +225,11 @@
raise HTTPBadRequest( detail="Missing required parameter 'id'." )
repository_metadata = metadata_util.get_repository_metadata_by_id( trans, repository_metadata_id )
if repository_metadata is None:
- log.debug( 'Cannot locate repository_metadata with id %s' % str( repository_metadata_id ) )
+ decoded_repository_metadata_id = trans.security.decode_id( repository_metadata_id )
+ log.debug( 'Cannot locate repository_metadata with id %s' % str( decoded_repository_metadata_id ) )
return {}
+ else:
+ decoded_repository_metadata_id = repository_metadata.id
flush_needed = False
for key, new_value in payload.items():
if key == 'time_last_tested':
@@ -239,6 +244,8 @@
setattr( repository_metadata, key, new_value )
flush_needed = True
if flush_needed:
+ log.debug( 'Updating repository_metadata record with id %s and changeset_revision %s.' % \
+ ( str( decoded_repository_metadata_id ), str( repository_metadata.changeset_revision ) ) )
trans.sa_session.add( repository_metadata )
trans.sa_session.flush()
trans.sa_session.refresh( repository_metadata )
@@ -246,5 +253,5 @@
value_mapper=self.__get_value_mapper( trans ) )
repository_metadata_dict[ 'url' ] = web.url_for( controller='repository_revisions',
action='show',
- id=trans.security.encode_id( repository_metadata.id ) )
+ id=repository_metadata_id )
return repository_metadata_dict
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dan: Change log.error to log.debug.
by commits-noreply@bitbucket.org 17 Jan '14
by commits-noreply@bitbucket.org 17 Jan '14
17 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/8704a185d43e/
Changeset: 8704a185d43e
User: dan
Date: 2014-01-17 21:45:04
Summary: Change log.error to log.debug.
Affected #: 1 file
diff -r 82b5aef7a1da9e4129ba2a3920a54048642cc991 -r 8704a185d43ef02b0dd763a89a9b003df0326d90 lib/galaxy/tools/data/__init__.py
--- a/lib/galaxy/tools/data/__init__.py
+++ b/lib/galaxy/tools/data/__init__.py
@@ -400,7 +400,7 @@
if fields not in self.data or allow_duplicates:
self.data.append( fields )
else:
- log.error( "Attempted to add fields (%s) to data table '%s', but this entry already exists and allow_duplicates is False.", fields, self.name )
+ log.debug( "Attempted to add fields (%s) to data table '%s', but this entry already exists and allow_duplicates is False.", fields, self.name )
is_error = True
else:
log.error( "Attempted to add fields (%s) to data table '%s', but there were not enough fields specified ( %i < %i ).", fields, self.name, len( fields ), self.largest_index + 1 )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Enhance setting tool shed repository metadata to support tool dependency recipes that define installation of a binary but do not also include a recipe for installing and compiling from source.
by commits-noreply@bitbucket.org 17 Jan '14
by commits-noreply@bitbucket.org 17 Jan '14
17 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/82b5aef7a1da/
Changeset: 82b5aef7a1da
User: greg
Date: 2014-01-17 19:49:10
Summary: Enhance setting tool shed repository metadata to support tool dependency recipes that define installation of a binary but do not also include a recipe for installing and compiling from source.
Affected #: 3 files
diff -r 79c1a31e269d4668d125c1a277549617d34dae13 -r 82b5aef7a1da9e4129ba2a3920a54048642cc991 lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/fabric_util.py
@@ -303,7 +303,8 @@
with make_tmp_dir() as work_dir:
with lcd( work_dir ):
# The first action in the list of actions will be the one that defines the installation process. There
- # are currently only two supported processes; download_by_url and clone via a "shell_command" action type.
+ # are currently three supported processes; download_binary, download_by_url and clone via a "shell_command"
+ # action type.
action_type, action_dict = actions[ 0 ]
if action_type == 'download_binary':
url = action_dict[ 'url' ]
@@ -316,11 +317,13 @@
downloaded_filename = td_common_util.download_binary( url, work_dir )
# Filter out any actions that are not download_binary, chmod, or set_environment.
filtered_actions = filter_actions_after_binary_installation( actions[ 1: ] )
- # Set actions to the same, so that the current download_binary doesn't get re-run in the filtered actions below.
+ # Set actions to the same, so that the current download_binary doesn't get re-run in the
+ # filtered actions below.
actions = filtered_actions
except Exception, e:
log.exception( str( e ) )
- # No binary exists, or there was an error downloading the binary from the generated URL. Proceed with the remaining actions.
+ # No binary exists, or there was an error downloading the binary from the generated URL.
+ # Proceed with the remaining actions.
filtered_actions = actions[ 1: ]
action_type, action_dict = filtered_actions[ 0 ]
# If the downloaded file exists, move it to $INSTALL_DIR. Put this outside the try/catch above so that
@@ -345,8 +348,9 @@
is_binary = action_dict.get( 'is_binary', False )
log.debug( 'Attempting to download via url: %s', url )
if 'target_filename' in action_dict:
- # Sometimes compressed archives extract their content to a folder other than the default defined file name. Using this
- # attribute will ensure that the file name is set appropriately and can be located after download, decompression and extraction.
+ # Sometimes compressed archives extract their content to a folder other than the default
+ # defined file name. Using this attribute will ensure that the file name is set appropriately
+ # and can be located after download, decompression and extraction.
downloaded_filename = action_dict[ 'target_filename' ]
else:
downloaded_filename = os.path.split( url )[ -1 ]
@@ -374,8 +378,9 @@
filtered_actions = actions[ 1: ]
url = action_dict[ 'url' ]
if 'target_filename' in action_dict:
- # Sometimes compressed archives extracts their content to a folder other than the default defined file name. Using this
- # attribute will ensure that the file name is set appropriately and can be located after download, decompression and extraction.
+ # Sometimes compressed archives extracts their content to a folder other than the default
+ # defined file name. Using this attribute will ensure that the file name is set appropriately
+ # and can be located after download, decompression and extraction.
filename = action_dict[ 'target_filename' ]
else:
filename = url.split( '/' )[ -1 ]
diff -r 79c1a31e269d4668d125c1a277549617d34dae13 -r 82b5aef7a1da9e4129ba2a3920a54048642cc991 lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py
--- a/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py
+++ b/lib/tool_shed/galaxy_install/tool_dependencies/td_common_util.py
@@ -324,31 +324,37 @@
def parse_package_elem( package_elem, platform_info_dict=None, include_after_install_actions=True ):
"""
- Parse a <package> element within a tool dependency definition and return a list of action tuples. This method is called when setting
- metadata on a repository that includes a tool_dependencies.xml file or when installing a repository that includes a tool_dependencies.xml
- file. If installing, platform_info_dict must be a valid dictionary and include_after_install_actions must be True.
+ Parse a <package> element within a tool dependency definition and return a list of action tuples.
+ This method is called when setting metadata on a repository that includes a tool_dependencies.xml
+ file or when installing a repository that includes a tool_dependencies.xml file. If installing,
+ platform_info_dict must be a valid dictionary and include_after_install_actions must be True.
"""
- # The actions_elem_tuples list contains <actions> tag sets (possibly inside of an <actions_group> tag set) to be processed in the order
- # they are defined in the tool_dependencies.xml file.
+ # The actions_elem_tuples list contains <actions> tag sets (possibly inside of an <actions_group>
+ # tag set) to be processed in the order they are defined in the tool_dependencies.xml file.
actions_elem_tuples = []
- # The tag sets that will go into the actions_elem_list are those that install a compiled binary if the architecture and operating system
- # match it's defined attributes. If compiled binary is not installed, the first <actions> tag set [following those that have the os and
- # architecture attributes] that does not have os or architecture attributes will be processed. This tag set must contain the recipe for
- # downloading and compiling source.
+ # The tag sets that will go into the actions_elem_list are those that install a compiled binary if
+ # the architecture and operating system match it's defined attributes. If compiled binary is not
+ # installed, the first <actions> tag set [following those that have the os and architecture attributes]
+ # that does not have os or architecture attributes will be processed. This tag set must contain the
+ # recipe for downloading and compiling source.
actions_elem_list = []
for elem in package_elem:
if elem.tag == 'actions':
- # We have an <actions> tag that should not be matched against a specific combination of architecture and operating system.
+ # We have an <actions> tag that should not be matched against a specific combination of
+ # architecture and operating system.
in_actions_group = False
actions_elem_tuples.append( ( in_actions_group, elem ) )
elif elem.tag == 'actions_group':
- # We have an actions_group element, and its child <actions> elements should therefore be compared with the current operating system
+ # We have an actions_group element, and its child <actions> elements should therefore be compared
+ # with the current operating system
# and processor architecture.
in_actions_group = True
- # Record the number of <actions> elements so we can filter out any <action> elements that precede <actions> elements.
+ # Record the number of <actions> elements so we can filter out any <action> elements that precede
+ # <actions> elements.
actions_elem_count = len( elem.findall( 'actions' ) )
- # Record the number of <actions> elements that have both architecture and os specified, in order to filter out any
- # platform-independent <actions> elements that come before platform-specific <actions> elements.
+ # Record the number of <actions> elements that have both architecture and os specified, in order
+ # to filter out any platform-independent <actions> elements that come before platform-specific
+ # <actions> elements.
platform_actions_elements = []
for actions_elem in elem.findall( 'actions' ):
if actions_elem.get( 'architecture' ) is not None and actions_elem.get( 'os' ) is not None:
@@ -356,8 +362,9 @@
platform_actions_element_count = len( platform_actions_elements )
platform_actions_elements_processed = 0
actions_elems_processed = 0
- # The tag sets that will go into the after_install_actions list are <action> tags instead of <actions> tags. These will be processed
- # only if they are at the very end of the <actions_group> tag set (after all <actions> tag sets). See below for details.
+ # The tag sets that will go into the after_install_actions list are <action> tags instead of <actions>
+ # tags. These will be processed only if they are at the very end of the <actions_group> tag set (after
+ # all <actions> tag sets). See below for details.
after_install_actions = []
# Inspect the <actions_group> element and build the actions_elem_list and the after_install_actions list.
for child_element in elem:
@@ -365,60 +372,71 @@
actions_elems_processed += 1
system = child_element.get( 'os' )
architecture = child_element.get( 'architecture' )
- # Skip <actions> tags that have only one of architecture or os specified, in order for the count in
- # platform_actions_elements_processed to remain accurate.
+ # Skip <actions> tags that have only one of architecture or os specified, in order for the
+ # count in platform_actions_elements_processed to remain accurate.
if ( system and not architecture ) or ( architecture and not system ):
log.debug( 'Error: Both architecture and os attributes must be specified in an <actions> tag.' )
continue
- # Since we are inside an <actions_group> tag set, compare it with our current platform information and filter the <actions>
- # tag sets that don't match. Require both the os and architecture attributes to be defined in order to find a match.
+ # Since we are inside an <actions_group> tag set, compare it with our current platform information
+ # and filter the <actions> tag sets that don't match. Require both the os and architecture attributes
+ # to be defined in order to find a match.
if system and architecture:
platform_actions_elements_processed += 1
- # If either the os or architecture do not match the platform, this <actions> tag will not be considered a match. Skip
- # it and proceed with checking the next one.
+ # If either the os or architecture do not match the platform, this <actions> tag will not be
+ # considered a match. Skip it and proceed with checking the next one.
if platform_info_dict:
if platform_info_dict[ 'os' ] != system or platform_info_dict[ 'architecture' ] != architecture:
continue
else:
- # We must not be installing a repository into Galaxy, so determining if we can install a binary is not necessary.
+ # We must not be installing a repository into Galaxy, so determining if we can install a
+ # binary is not necessary.
continue
else:
- # <actions> tags without both os and architecture attributes are only allowed to be specified after platform-specific
- # <actions> tags. If we find a platform-independent <actions> tag before all platform-specific <actions> tags have been
- # processed.
+ # <actions> tags without both os and architecture attributes are only allowed to be specified
+ # after platform-specific <actions> tags. If we find a platform-independent <actions> tag before
+ # all platform-specific <actions> tags have been processed.
if platform_actions_elements_processed < platform_actions_element_count:
- message = 'Error: <actions> tags without os and architecture attributes are only allowed after all <actions> tags with '
- message += 'os and architecture attributes have been defined. Skipping the <actions> tag set with no os or architecture '
- message += 'attributes that has been defined between two <actions> tag sets that have these attributes defined. '
- log.debug( message )
+ debug_msg = 'Error: <actions> tags without os and architecture attributes are only allowed '
+ debug_msg += 'after all <actions> tags with os and architecture attributes have been defined. '
+ debug_msg += 'Skipping the <actions> tag set with no os or architecture attributes that has '
+ debug_msg += 'been defined between two <actions> tag sets that have these attributes defined. '
+ log.debug( debug_msg )
continue
- # If we reach this point, it means one of two things: 1) The system and architecture attributes are not defined in this
- # <actions> tag, or 2) The system and architecture attributes are defined, and they are an exact match for the current
- # platform. Append the child element to the list of elements to process.
+ # If we reach this point, it means one of two things: 1) The system and architecture attributes are
+ # not defined in this <actions> tag, or 2) The system and architecture attributes are defined, and
+ # they are an exact match for the current platform. Append the child element to the list of elements
+ # to process.
actions_elem_list.append( child_element )
elif child_element.tag == 'action':
# Any <action> tags within an <actions_group> tag set must come after all <actions> tags.
if actions_elems_processed == actions_elem_count:
- # If all <actions> elements have been processed, then this <action> element can be appended to the list of actions to
- # execute within this group.
+ # If all <actions> elements have been processed, then this <action> element can be appended to the
+ # list of actions to execute within this group.
after_install_actions.append( child_element )
else:
- # If any <actions> elements remain to be processed, then log a message stating that <action> elements are not allowed
- # to precede any <actions> elements within an <actions_group> tag set.
- message = 'Error: <action> tags are only allowed at the end of an <actions_group> tag set after all <actions> tags. '
- message += 'Skipping <%s> element with type %s.' % ( child_element.tag, child_element.get( 'type' ) )
- log.debug( message )
+ # If any <actions> elements remain to be processed, then log a message stating that <action>
+ # elements are not allowed to precede any <actions> elements within an <actions_group> tag set.
+ debug_msg = 'Error: <action> tags are only allowed at the end of an <actions_group> tag set after '
+ debug_msg += 'all <actions> tags. Skipping <%s> element with type %s.' % \
+ ( child_element.tag, child_element.get( 'type', 'unknown' ) )
+ log.debug( debug_msg )
continue
if platform_info_dict is None and not include_after_install_actions:
# We must be setting metadata on a repository.
- actions_elem_tuples.append( ( in_actions_group, actions_elem_list[ 0 ] ) )
+ if len( actions_elem_list ) >= 1:
+ actions_elem_tuples.append( ( in_actions_group, actions_elem_list[ 0 ] ) )
+ else:
+ # We are processing a recipe that contains only an <actions_group> tag set for installing a binary,
+ # but does not include an additional recipe for installing and compiling from source.
+ actions_elem_tuples.append( ( in_actions_group, [] ) )
elif platform_info_dict is not None and include_after_install_actions:
# We must be installing a repository.
if after_install_actions:
actions_elem_list.extend( after_install_actions )
actions_elem_tuples.append( ( in_actions_group, actions_elem_list ) )
else:
- # Skip any element that is not <actions> or <actions_group> - this will skip comments, <repository> tags and <readme> tags.
+ # Skip any element that is not <actions> or <actions_group> - this will skip comments, <repository> tags
+ # and <readme> tags.
in_actions_group = False
continue
return actions_elem_tuples
diff -r 79c1a31e269d4668d125c1a277549617d34dae13 -r 82b5aef7a1da9e4129ba2a3920a54048642cc991 lib/tool_shed/util/metadata_util.py
--- a/lib/tool_shed/util/metadata_util.py
+++ b/lib/tool_shed/util/metadata_util.py
@@ -791,26 +791,30 @@
if sub_elem.tag == 'readme':
requirements_dict[ 'readme' ] = sub_elem.text
elif sub_elem.tag == 'repository':
- # We have a complex repository dependency. If the returned value of repository_dependency_is_valid is True, the tool
- # dependency definition will be set as invalid. This is currently the only case where a tool dependency definition is
- # considered invalid.
- repository_dependency_tup, repository_dependency_is_valid, error_message = handle_repository_elem( app=app,
- repository_elem=sub_elem,
- only_if_compiling_contained_td=False )
+ # We have a complex repository dependency. If the returned value of repository_dependency_is_valid
+ # is True, the tool dependency definition will be set as invalid. This is currently the only case
+ # where a tool dependency definition is considered invalid.
+ repository_dependency_tup, repository_dependency_is_valid, error_message = \
+ handle_repository_elem( app=app, repository_elem=sub_elem, only_if_compiling_contained_td=False )
elif sub_elem.tag == 'install':
package_install_version = sub_elem.get( 'version', '1.0' )
if package_install_version == '1.0':
- # Complex repository dependencies can be defined within the last <actions> tag set contained in an <actions_group> tag set.
- # Comments, <repository> tag sets and <readme> tag sets will be skipped in td_common_util.parse_package_elem().
- actions_elem_tuples = td_common_util.parse_package_elem( sub_elem, platform_info_dict=None, include_after_install_actions=False )
+ # Complex repository dependencies can be defined within the last <actions> tag set contained in an
+ # <actions_group> tag set. Comments, <repository> tag sets and <readme> tag sets will be skipped
+ # in td_common_util.parse_package_elem().
+ actions_elem_tuples = td_common_util.parse_package_elem( sub_elem,
+ platform_info_dict=None,
+ include_after_install_actions=False )
if actions_elem_tuples:
- # We now have a list of a single tuple that looks something like: [(True, <Element 'actions' at 0x104017850>)]
+ # We now have a list of a single tuple that looks something like:
+ # [(True, <Element 'actions' at 0x104017850>)]
actions_elem_tuple = actions_elem_tuples[ 0 ]
in_actions_group, actions_elem = actions_elem_tuple
if in_actions_group:
- # Since we're inside an <actions_group> tag set, inspect the actions_elem to see if a complex repository dependency
- # is defined. By definition, complex repository dependency definitions contained within the last <actions> tag set
- # within an <actions_group> tag set will have the value of "only_if_compiling_contained_td" set to True in
+ # Since we're inside an <actions_group> tag set, inspect the actions_elem to see if a complex
+ # repository dependency is defined. By definition, complex repository dependency definitions
+ # contained within the last <actions> tag set within an <actions_group> tag set will have the
+ # value of "only_if_compiling_contained_td" set to True in
for action_elem in actions_elem:
if action_elem.tag == 'package':
# <package name="libgtextutils" version="0.6">
@@ -834,7 +838,8 @@
# Append the error message to the requirements_dict.
requirements_dict[ 'error' ] = error_message
invalid_tool_dependencies_dict[ dependency_key ] = requirements_dict
- return valid_tool_dependencies_dict, invalid_tool_dependencies_dict, repository_dependency_tup, repository_dependency_is_valid, error_message
+ return valid_tool_dependencies_dict, invalid_tool_dependencies_dict, repository_dependency_tup, \
+ repository_dependency_is_valid, error_message
def generate_repository_dependency_metadata( app, repository_dependencies_config, metadata_dict ):
"""
@@ -1986,7 +1991,8 @@
content_alert_str=content_alert_str,
**kwd )
if error_message:
- # FIXME: This probably should not redirect since this method is called from the upload controller as well as the repository controller.
+ # FIXME: This probably should not redirect since this method is called from the upload controller as well
+ # as the repository controller.
# If there is an error, display it.
return trans.response.send_redirect( web.url_for( controller='repository',
action='manage_repository',
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: library history ‘back’ button bug removal
by commits-noreply@bitbucket.org 17 Jan '14
by commits-noreply@bitbucket.org 17 Jan '14
17 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/79c1a31e269d/
Changeset: 79c1a31e269d
User: martenson
Date: 2014-01-17 18:19:04
Summary: library history ‘back’ button bug removal
Affected #: 3 files
diff -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae -r 79c1a31e269d4668d125c1a277549617d34dae13 lib/galaxy/webapps/galaxy/api/authenticate.py
--- a/lib/galaxy/webapps/galaxy/api/authenticate.py
+++ b/lib/galaxy/webapps/galaxy/api/authenticate.py
@@ -22,8 +22,8 @@
* GET /api/authenticate/baseauth
returns an API key for authenticated user based on BaseAuth headers
+ :returns: api_key in json format
:rtype: dict
- :returns: api_key in json format
:raises: ObjectNotFound, HTTPBadRequest
"""
@@ -48,9 +48,20 @@
return dict( api_key= api_key_row.key )
def _decode_baseauth( self, encoded_str ):
- """Decode an encrypted HTTP basic authentication string. Returns a tuple of
+ """
+ Decode an encrypted HTTP basic authentication string. Returns a tuple of
the form (email, password), and raises a HTTPBadRequest exception if
nothing could be decoded.
+
+ :param encoded_str: BaseAuth string encoded base64
+ :type encoded_str: string
+
+ :returns: email of the user
+ :rtype: string
+ :returns: password of the user
+ :rtype: string
+
+ :raises: HTTPBadRequest
"""
split = encoded_str.strip().split( ' ' )
diff -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae -r 79c1a31e269d4668d125c1a277549617d34dae13 static/scripts/galaxy.library.js
--- a/static/scripts/galaxy.library.js
+++ b/static/scripts/galaxy.library.js
@@ -406,9 +406,9 @@
if (typeof folder_id === 'undefined') {
return false;
} else if (folder_id === '0'){
- library_router.navigate('#', {trigger: true, replace: true});
+ library_router.navigate('/', {trigger: true, replace: false});
} else {
- library_router.navigate('folders/' + folder_id, {trigger: true, replace: true});
+ library_router.navigate('folders/' + folder_id, {trigger: true, replace: false});
}
},
@@ -984,9 +984,9 @@
}
});
-Backbone.history.start();
+Backbone.history.start({pushState: false});
-return this
+// return this
}
});
diff -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae -r 79c1a31e269d4668d125c1a277549617d34dae13 static/scripts/packed/galaxy.library.js
--- a/static/scripts/packed/galaxy.library.js
+++ b/static/scripts/packed/galaxy.library.js
@@ -1,1 +1,1 @@
-var view=null;var library_router=null;var responses=[];define(["galaxy.modal","galaxy.masthead","utils/galaxy.utils","libs/toastr"],function(k,l,h,n){var f=Backbone.Model.extend({urlRoot:"/api/libraries"});var c=Backbone.Model.extend({urlRoot:"/api/folders"});var o=Backbone.Collection.extend({url:"/api/libraries",model:f});var i=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var d=Backbone.Collection.extend({model:i});var e=Backbone.Model.extend({defaults:{folder:new d(),full_path:"unknown",urlRoot:"/api/folders/",id:"unknown"},parse:function(r){this.full_path=r[0].full_path;this.get("folder").reset(r[1].folder_contents);return r}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var j=Backbone.Model.extend({url:"/api/histories/"});var p=Backbone.Collection.extend({url:"/api/histories",model:j});var q=Backbone.Router.extend({routes:{"":"libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var m=Backbone.View.extend({el:"#center",progress:0,progressStep:1,lastSelectedHistory:"",modal:null,folders:null,initialize:function(){this.folders=[];this.queue=jQuery.Deferred();this.queue.resolve()},templateFolder:function(){var r=[];r.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');r.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');r.push('<div id="library_folder_toolbar" >');r.push(' <button title="Create New Folder" id="toolbtn_create_folder" class="btn btn-primary" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');r.push(' <button id="toolbtn_bulk_import" class="btn btn-primary" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-external-link"></span> to history</button>');r.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');r.push(' <button id="drop_toggle" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">');r.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');r.push(" </button>");r.push(' <ul class="dropdown-menu" role="menu">');r.push(' <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');r.push(" </ul>");r.push(" </div>");r.push("</div>");r.push('<div class="library_breadcrumb">');r.push('<a title="Return to the list of libraries" href="#">Libraries</a><b>|</b> ');r.push("<% _.each(path, function(path_item) { %>");r.push("<% if (path_item[0] != id) { %>");r.push('<a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a><b>|</b> ');r.push("<% } else { %>");r.push('<span title="You are in this folder"><%- path_item[1] %></span>');r.push("<% } %>");r.push("<% }); %>");r.push("</div>");r.push('<table id="folder_table" class="table table-condensed">');r.push(" <thead>");r.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');r.push(' <th class="button_heading">view</th>');r.push(" <th>name</th>");r.push(" <th>data type</th>");r.push(" <th>size</th>");r.push(" <th>date (UTC)</th>");r.push(" </thead>");r.push(" <tbody>");r.push(" <td></td>");r.push(' <td><button title="Go to parent folder" type="button" data-id="<%- upper_folder_id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-arrow-up"></span> .. go up</td>');r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" </tr>");r.push(" <% _.each(items, function(content_item) { %>");r.push(' <tr class="folder_row light" id="<%- content_item.id %>">');r.push(' <% if (content_item.get("type") === "folder") { %>');r.push(" <td></td>");r.push(' <td><button title="Open this folder" type="button" data-id="<%- content_item.id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-folder-open"></span> browse</td>');r.push(' <td><%- content_item.get("name") %>');r.push(' <% if (content_item.get("item_count") === 0) { %>');r.push(' <span class="muted">(empty folder)</span>');r.push(" <% } %>");r.push(" </td>");r.push(" <td>folder</td>");r.push(' <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>');r.push(" <% } else { %>");r.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');r.push(" <td>");r.push(' <button title="See details of this dataset" type="button" class="library-dataset btn btn-default btn-xs">');r.push(' <span class="fa fa-eye"></span> details');r.push(" </button>");r.push(" </td>");r.push(' <td><%- content_item.get("name") %></td>');r.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');r.push(' <td><%= _.escape(content_item.get("readable_size")) %></td>');r.push(" <% } %> ");r.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>');r.push(" </tr>");r.push(" <% }); %>");r.push(" ");r.push(" </tbody>");r.push("</table>");r.push("</div>");return r.join("")},templateDatasetModal:function(){var r=[];r.push('<div id="dataset_info_modal">');r.push(' <table class="table table-striped table-condensed">');r.push(" <tr>");r.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');r.push(' <td><%= _.escape(item.get("name")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Data type</th>');r.push(' <td><%= _.escape(item.get("data_type")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Genome build</th>');r.push(' <td><%= _.escape(item.get("genome_build")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Size</th>');r.push(" <td><%= _.escape(size) %></td>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Date uploaded (UTC)</th>');r.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Uploaded by</th>');r.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');r.push(" </tr>");r.push(' <tr scope="row">');r.push(' <th scope="row">Data Lines</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Comment Lines</th>');r.push(' <% if (item.get("metadata_comment_lines") === "") { %>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');r.push(" <% } else { %>");r.push(' <td scope="row">unknown</td>');r.push(" <% } %>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Number of Columns</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Column Types</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Miscellaneous information</th>');r.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');r.push(" </tr>");r.push(" </table>");r.push(' <pre class="peek">');r.push(" </pre>");r.push("</div>");return r.join("")},templateHistorySelectInModal:function(){var r=[];r.push('<span id="history_modal_combo" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateBulkImportInModal:function(){var r=[];r.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateProgressBar:function(){var r=[];r.push('<div class="import_text">');r.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");r.push("</div>");r.push('<div class="progress">');r.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');r.push(' <span class="completion_span">0% Complete</span>');r.push(" </div>");r.push("</div>");r.push("");return r.join("")},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return tmpl_array.join("")},events:{"click #select-all-checkboxes":"selectAll","click .folder_row":"selectClickedRow","click #toolbtn_bulk_import":"modalBulkImport","click #toolbtn_dl":"bulkDownload","click .library-dataset":"showDatasetDetails","click #toolbtn_create_folder":"createFolderFromModal","click .btn_open_folder":"navigateToFolder"},render:function(r){$("#center").css("overflow","auto");view=this;var t=this;var s=new e({id:r.id});s.url=s.attributes.urlRoot+r.id+"/contents";s.fetch({success:function(u){for(var w=0;w<s.attributes.folder.models.length;w++){var v=s.attributes.folder.models[w];if(v.get("type")==="file"){v.set("readable_size",t.size_to_string(v.get("file_size")))}}var y=s.full_path;var z;if(y.length===1){z=0}else{z=y[y.length-2][0]}var x=_.template(t.templateFolder(),{path:s.full_path,items:s.attributes.folder.models,id:r.id,upper_folder_id:z});t.$el.html(x)},error:function(){n.error("An error occured :(")}})},size_to_string:function(r){var s="";if(r>=100000000000){r=r/100000000000;s="TB"}else{if(r>=100000000){r=r/100000000;s="GB"}else{if(r>=100000){r=r/100000;s="MB"}else{if(r>=100){r=r/100;s="KB"}else{r=r*10;s="b"}}}}return(Math.round(r)/10)+s},navigateToFolder:function(s){var r=$(s.target).attr("data-id");if(typeof r==="undefined"){return false}else{if(r==="0"){library_router.navigate("#",{trigger:true,replace:true})}else{library_router.navigate("folders/"+r,{trigger:true,replace:true})}}},showDatasetDetails:function(u){u.preventDefault();var v=$(u.target).parent().parent().attr("id");var t=new i();var s=new p();t.id=v;var r=this;t.fetch({success:function(w){s.fetch({success:function(x){r.renderModalAfterFetch(w,x)},error:function(){n.error("An error occured during fetching histories:(");r.renderModalAfterFetch(w)}})},error:function(){n.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(w,t){var u=this.size_to_string(w.get("file_size"));var v=_.template(this.templateDatasetModal(),{item:w,size:u});var s=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Dataset Details",body:v,buttons:{Import:function(){s.importCurrentIntoHistory()},Download:function(){s.downloadCurrent()},Close:function(){s.modal.hideOrDestroy()}}});$(".peek").html(w.get("peek"));if(typeof history.models!==undefined){var r=_.template(this.templateHistorySelectInModal(),{histories:t.models});$(this.modal.elMain).find(".buttons").prepend(r);if(s.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(s.lastSelectedHistory)}}this.modal.show()},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var r=[];r.push($("#id_row").attr("data-id"));var s="/api/libraries/datasets/download/uncompressed";var t={ldda_ids:r};folderContentView.processDownload(s,t);this.modal.enableButton("Import");this.modal.enableButton("Download")},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var t=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=t;var r=$("#id_row").attr("data-id");var u=new b();var s=this;u.url=u.urlRoot+t+"/contents";u.save({content:r,source:"library"},{success:function(){n.success("Dataset imported");s.modal.enableButton("Import");s.modal.enableButton("Download")},error:function(){n.error("An error occured! Dataset not imported. Please try again.");s.modal.enableButton("Import");s.modal.enableButton("Download")}})},selectAll:function(s){var r=s.target.checked;that=this;$(":checkbox").each(function(){this.checked=r;$row=$(this.parentElement.parentElement);(r)?that.makeDarkRow($row):that.makeWhiteRow($row)});this.checkTools()},selectClickedRow:function(s){var u="";var r;var t;if(s.target.localName==="input"){u=s.target;r=$(s.target.parentElement.parentElement);t="input"}else{if(s.target.localName==="td"){u=$("#"+s.target.parentElement.id).find(":checkbox")[0];r=$(s.target.parentElement);t="td"}}if(u===""){s.stopPropagation();return}if(u===undefined){s.stopPropagation();return}if(u.checked){if(t==="td"){u.checked="";this.makeWhiteRow(r)}else{if(t==="input"){this.makeDarkRow(r)}}}else{if(t==="td"){u.checked="selected";this.makeDarkRow(r)}else{if(t==="input"){this.makeWhiteRow(r)}}}this.checkTools()},makeDarkRow:function(r){r.removeClass("light");r.find("a").removeClass("light");r.addClass("dark");r.find("a").addClass("dark")},makeWhiteRow:function(r){r.removeClass("dark");r.find("a").removeClass("dark");r.addClass("light");r.find("a").addClass("light")},checkTools:function(){var r=$("#folder_table").find(":checked");if(r.length>0){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}else{$("#toolbtn_bulk_import").hide();$("#toolbtn_dl").hide()}},modalBulkImport:function(){var s=this;var r=new p();r.fetch({success:function(t){var u=_.template(s.templateBulkImportInModal(),{histories:t.models});s.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Import into History",body:u,buttons:{Import:function(){s.importAllIntoHistory()},Close:function(){s.modal.hideOrDestroy()}}});s.modal.show()},error:function(){n.error("An error occured :(")}})},importAllIntoHistory:function(){this.modal.disableButton("Import");var t=$("select[name=dataset_import_bulk] option:selected").val();var x=$("select[name=dataset_import_bulk] option:selected").text();var z=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){z.push(this.parentElement.parentElement.id)}});var y=_.template(this.templateProgressBar(),{history_name:x});$(this.modal.elMain).find(".modal-body").html(y);var u=100/z.length;this.initProgress(u);var r=[];for(var s=z.length-1;s>=0;s--){library_dataset_id=z[s];var v=new b();var w=this;v.url=v.urlRoot+t+"/contents";v.content=library_dataset_id;v.source="library";r.push(v)}this.chainCall(r)},chainCall:function(s){var r=this;var t=s.pop();if(typeof t==="undefined"){n.success("All datasets imported");this.modal.hideOrDestroy();return}var u=$.when(t.save({content:t.content,source:t.source})).done(function(v){r.updateProgress();responses.push(v);r.chainCall(s)})},initProgress:function(r){this.progress=0;this.progressStep=r},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(r,v){var t=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){t.push(this.parentElement.parentElement.id)}});var s="/api/libraries/datasets/download/"+v;var u={ldda_ids:t};this.processDownload(s,u,"get")},processDownload:function(s,t,u){if(s&&t){t=typeof t=="string"?t:$.param(t);var r="";$.each(t.split("&"),function(){var v=this.split("=");r+='<input type="hidden" name="'+v[0]+'" value="'+v[1]+'" />'});$('<form action="'+s+'" method="'+(u||"post")+'">'+r+"</form>").appendTo("body").submit().remove();n.info("Your download will begin soon")}},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Create New Folder",body:this.templateNewFolderInModal(),buttons:{Create:function(){r.create_new_folder_event()},Close:function(){r.modal.hideOrDestroy();r.modal=null}}});this.modal.show()},create_new_folder_event:function(){var r=this.serialize_new_folder();if(this.validate_new_folder(r)){var t=new c();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];t.url=t.urlRoot+"/"+current_folder_id;var s=this;t.save(r,{success:function(u){s.modal.hideOrDestroy();n.success("Folder created");s.render({id:current_folder_id})},error:function(){n.error("An error occured :(")}})}else{n.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(r){return r.name!==""}});var a=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"show_library_modal"},initialize:function(){},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; overflow: auto !important; ">');tmpl_array.push("");tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push('<a href="" id="create_new_library_btn" class="btn btn-primary file ">New Library</a>');tmpl_array.push('<table class="table table-condensed">');tmpl_array.push(" <thead>");tmpl_array.push(' <th class="button_heading"></th>');tmpl_array.push(" <th>name</th>");tmpl_array.push(" <th>description</th>");tmpl_array.push(" <th>synopsis</th> ");tmpl_array.push(" <th>model type</th> ");tmpl_array.push(" </thead>");tmpl_array.push(" <tbody>");tmpl_array.push(" <% _.each(libraries, function(library) { %>");tmpl_array.push(" <tr>");tmpl_array.push(' <td><button title="Open this library" type="button" data-id="<%- library.get("root_folder_id") %>" class="btn_open_folder btn btn-default btn-xs">');tmpl_array.push(' <span class="fa fa-folder-open"></span> browse</td>');tmpl_array.push(' <td><%- library.get("name") %></td>');tmpl_array.push(' <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("model_class")) %></td>');tmpl_array.push(" </tr>");tmpl_array.push(" <% }); %>");tmpl_array.push(" </tbody>");tmpl_array.push("</table>");tmpl_array.push("</div>");return tmpl_array.join("")},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")},render:function(){$("#center").css("overflow","auto");var r=this;libraries=new o();libraries.fetch({success:function(s){var t=_.template(r.templateLibraryList(),{libraries:s.models});r.$el.html(t)},error:function(t,s){if(s.statusCode().status===403){n.info("Please log in first. Redirecting to login page in 3s.");setTimeout(r.redirectToLogin,3000)}else{n.error("An error occured. Please try again.")}}})},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},modal:null,show_library_modal:function(s){s.preventDefault();s.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){r.create_new_library_event()},Close:function(){r.modal.hideOrDestroy()}}});this.modal.show()},create_new_library_event:function(){var t=this.serialize_new_library();if(this.validate_new_library(t)){var s=new f();var r=this;s.save(t,{success:function(u){r.modal.hideOrDestroy();r.clear_library_modal();r.render();n.success("Library created")},error:function(){n.error("An error occured :(")}})}else{n.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(r){return r.name!==""}});var g=Backbone.View.extend({folderContentView:null,galaxyLibraryview:null,initialize:function(){folderContentView=new m();galaxyLibraryview=new a();library_router=new q();library_router.on("route:libraries",function(){galaxyLibraryview.render()});library_router.on("route:folder_content",function(r){folderContentView.render({id:r})});library_router.on("route:download",function(r,s){if($("#center").find(":checked").length===0){library_router.navigate("folders/"+r,{trigger:true,replace:true})}else{folderContentView.download(r,s);library_router.navigate("folders/"+r,{trigger:false,replace:true})}});Backbone.history.start();return this}});return{GalaxyApp:g}});
\ No newline at end of file
+var view=null;var library_router=null;var responses=[];define(["galaxy.modal","galaxy.masthead","utils/galaxy.utils","libs/toastr"],function(k,l,h,n){var f=Backbone.Model.extend({urlRoot:"/api/libraries"});var c=Backbone.Model.extend({urlRoot:"/api/folders"});var o=Backbone.Collection.extend({url:"/api/libraries",model:f});var i=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var d=Backbone.Collection.extend({model:i});var e=Backbone.Model.extend({defaults:{folder:new d(),full_path:"unknown",urlRoot:"/api/folders/",id:"unknown"},parse:function(r){this.full_path=r[0].full_path;this.get("folder").reset(r[1].folder_contents);return r}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var j=Backbone.Model.extend({url:"/api/histories/"});var p=Backbone.Collection.extend({url:"/api/histories",model:j});var q=Backbone.Router.extend({routes:{"":"libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var m=Backbone.View.extend({el:"#center",progress:0,progressStep:1,lastSelectedHistory:"",modal:null,folders:null,initialize:function(){this.folders=[];this.queue=jQuery.Deferred();this.queue.resolve()},templateFolder:function(){var r=[];r.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');r.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');r.push('<div id="library_folder_toolbar" >');r.push(' <button title="Create New Folder" id="toolbtn_create_folder" class="btn btn-primary" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');r.push(' <button id="toolbtn_bulk_import" class="btn btn-primary" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-external-link"></span> to history</button>');r.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');r.push(' <button id="drop_toggle" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">');r.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');r.push(" </button>");r.push(' <ul class="dropdown-menu" role="menu">');r.push(' <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');r.push(" </ul>");r.push(" </div>");r.push("</div>");r.push('<div class="library_breadcrumb">');r.push('<a title="Return to the list of libraries" href="#">Libraries</a><b>|</b> ');r.push("<% _.each(path, function(path_item) { %>");r.push("<% if (path_item[0] != id) { %>");r.push('<a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a><b>|</b> ');r.push("<% } else { %>");r.push('<span title="You are in this folder"><%- path_item[1] %></span>');r.push("<% } %>");r.push("<% }); %>");r.push("</div>");r.push('<table id="folder_table" class="table table-condensed">');r.push(" <thead>");r.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');r.push(' <th class="button_heading">view</th>');r.push(" <th>name</th>");r.push(" <th>data type</th>");r.push(" <th>size</th>");r.push(" <th>date (UTC)</th>");r.push(" </thead>");r.push(" <tbody>");r.push(" <td></td>");r.push(' <td><button title="Go to parent folder" type="button" data-id="<%- upper_folder_id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-arrow-up"></span> .. go up</td>');r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" </tr>");r.push(" <% _.each(items, function(content_item) { %>");r.push(' <tr class="folder_row light" id="<%- content_item.id %>">');r.push(' <% if (content_item.get("type") === "folder") { %>');r.push(" <td></td>");r.push(' <td><button title="Open this folder" type="button" data-id="<%- content_item.id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-folder-open"></span> browse</td>');r.push(' <td><%- content_item.get("name") %>');r.push(' <% if (content_item.get("item_count") === 0) { %>');r.push(' <span class="muted">(empty folder)</span>');r.push(" <% } %>");r.push(" </td>");r.push(" <td>folder</td>");r.push(' <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>');r.push(" <% } else { %>");r.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');r.push(" <td>");r.push(' <button title="See details of this dataset" type="button" class="library-dataset btn btn-default btn-xs">');r.push(' <span class="fa fa-eye"></span> details');r.push(" </button>");r.push(" </td>");r.push(' <td><%- content_item.get("name") %></td>');r.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');r.push(' <td><%= _.escape(content_item.get("readable_size")) %></td>');r.push(" <% } %> ");r.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>');r.push(" </tr>");r.push(" <% }); %>");r.push(" ");r.push(" </tbody>");r.push("</table>");r.push("</div>");return r.join("")},templateDatasetModal:function(){var r=[];r.push('<div id="dataset_info_modal">');r.push(' <table class="table table-striped table-condensed">');r.push(" <tr>");r.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');r.push(' <td><%= _.escape(item.get("name")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Data type</th>');r.push(' <td><%= _.escape(item.get("data_type")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Genome build</th>');r.push(' <td><%= _.escape(item.get("genome_build")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Size</th>');r.push(" <td><%= _.escape(size) %></td>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Date uploaded (UTC)</th>');r.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Uploaded by</th>');r.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');r.push(" </tr>");r.push(' <tr scope="row">');r.push(' <th scope="row">Data Lines</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Comment Lines</th>');r.push(' <% if (item.get("metadata_comment_lines") === "") { %>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');r.push(" <% } else { %>");r.push(' <td scope="row">unknown</td>');r.push(" <% } %>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Number of Columns</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Column Types</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Miscellaneous information</th>');r.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');r.push(" </tr>");r.push(" </table>");r.push(' <pre class="peek">');r.push(" </pre>");r.push("</div>");return r.join("")},templateHistorySelectInModal:function(){var r=[];r.push('<span id="history_modal_combo" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateBulkImportInModal:function(){var r=[];r.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateProgressBar:function(){var r=[];r.push('<div class="import_text">');r.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");r.push("</div>");r.push('<div class="progress">');r.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');r.push(' <span class="completion_span">0% Complete</span>');r.push(" </div>");r.push("</div>");r.push("");return r.join("")},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return tmpl_array.join("")},events:{"click #select-all-checkboxes":"selectAll","click .folder_row":"selectClickedRow","click #toolbtn_bulk_import":"modalBulkImport","click #toolbtn_dl":"bulkDownload","click .library-dataset":"showDatasetDetails","click #toolbtn_create_folder":"createFolderFromModal","click .btn_open_folder":"navigateToFolder"},render:function(r){$("#center").css("overflow","auto");view=this;var t=this;var s=new e({id:r.id});s.url=s.attributes.urlRoot+r.id+"/contents";s.fetch({success:function(u){for(var w=0;w<s.attributes.folder.models.length;w++){var v=s.attributes.folder.models[w];if(v.get("type")==="file"){v.set("readable_size",t.size_to_string(v.get("file_size")))}}var y=s.full_path;var z;if(y.length===1){z=0}else{z=y[y.length-2][0]}var x=_.template(t.templateFolder(),{path:s.full_path,items:s.attributes.folder.models,id:r.id,upper_folder_id:z});t.$el.html(x)},error:function(){n.error("An error occured :(")}})},size_to_string:function(r){var s="";if(r>=100000000000){r=r/100000000000;s="TB"}else{if(r>=100000000){r=r/100000000;s="GB"}else{if(r>=100000){r=r/100000;s="MB"}else{if(r>=100){r=r/100;s="KB"}else{r=r*10;s="b"}}}}return(Math.round(r)/10)+s},navigateToFolder:function(s){var r=$(s.target).attr("data-id");if(typeof r==="undefined"){return false}else{if(r==="0"){library_router.navigate("/",{trigger:true,replace:false})}else{library_router.navigate("folders/"+r,{trigger:true,replace:false})}}},showDatasetDetails:function(u){u.preventDefault();var v=$(u.target).parent().parent().attr("id");var t=new i();var s=new p();t.id=v;var r=this;t.fetch({success:function(w){s.fetch({success:function(x){r.renderModalAfterFetch(w,x)},error:function(){n.error("An error occured during fetching histories:(");r.renderModalAfterFetch(w)}})},error:function(){n.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(w,t){var u=this.size_to_string(w.get("file_size"));var v=_.template(this.templateDatasetModal(),{item:w,size:u});var s=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Dataset Details",body:v,buttons:{Import:function(){s.importCurrentIntoHistory()},Download:function(){s.downloadCurrent()},Close:function(){s.modal.hideOrDestroy()}}});$(".peek").html(w.get("peek"));if(typeof history.models!==undefined){var r=_.template(this.templateHistorySelectInModal(),{histories:t.models});$(this.modal.elMain).find(".buttons").prepend(r);if(s.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(s.lastSelectedHistory)}}this.modal.show()},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var r=[];r.push($("#id_row").attr("data-id"));var s="/api/libraries/datasets/download/uncompressed";var t={ldda_ids:r};folderContentView.processDownload(s,t);this.modal.enableButton("Import");this.modal.enableButton("Download")},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var t=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=t;var r=$("#id_row").attr("data-id");var u=new b();var s=this;u.url=u.urlRoot+t+"/contents";u.save({content:r,source:"library"},{success:function(){n.success("Dataset imported");s.modal.enableButton("Import");s.modal.enableButton("Download")},error:function(){n.error("An error occured! Dataset not imported. Please try again.");s.modal.enableButton("Import");s.modal.enableButton("Download")}})},selectAll:function(s){var r=s.target.checked;that=this;$(":checkbox").each(function(){this.checked=r;$row=$(this.parentElement.parentElement);(r)?that.makeDarkRow($row):that.makeWhiteRow($row)});this.checkTools()},selectClickedRow:function(s){var u="";var r;var t;if(s.target.localName==="input"){u=s.target;r=$(s.target.parentElement.parentElement);t="input"}else{if(s.target.localName==="td"){u=$("#"+s.target.parentElement.id).find(":checkbox")[0];r=$(s.target.parentElement);t="td"}}if(u===""){s.stopPropagation();return}if(u===undefined){s.stopPropagation();return}if(u.checked){if(t==="td"){u.checked="";this.makeWhiteRow(r)}else{if(t==="input"){this.makeDarkRow(r)}}}else{if(t==="td"){u.checked="selected";this.makeDarkRow(r)}else{if(t==="input"){this.makeWhiteRow(r)}}}this.checkTools()},makeDarkRow:function(r){r.removeClass("light");r.find("a").removeClass("light");r.addClass("dark");r.find("a").addClass("dark")},makeWhiteRow:function(r){r.removeClass("dark");r.find("a").removeClass("dark");r.addClass("light");r.find("a").addClass("light")},checkTools:function(){var r=$("#folder_table").find(":checked");if(r.length>0){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}else{$("#toolbtn_bulk_import").hide();$("#toolbtn_dl").hide()}},modalBulkImport:function(){var s=this;var r=new p();r.fetch({success:function(t){var u=_.template(s.templateBulkImportInModal(),{histories:t.models});s.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Import into History",body:u,buttons:{Import:function(){s.importAllIntoHistory()},Close:function(){s.modal.hideOrDestroy()}}});s.modal.show()},error:function(){n.error("An error occured :(")}})},importAllIntoHistory:function(){this.modal.disableButton("Import");var t=$("select[name=dataset_import_bulk] option:selected").val();var x=$("select[name=dataset_import_bulk] option:selected").text();var z=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){z.push(this.parentElement.parentElement.id)}});var y=_.template(this.templateProgressBar(),{history_name:x});$(this.modal.elMain).find(".modal-body").html(y);var u=100/z.length;this.initProgress(u);var r=[];for(var s=z.length-1;s>=0;s--){library_dataset_id=z[s];var v=new b();var w=this;v.url=v.urlRoot+t+"/contents";v.content=library_dataset_id;v.source="library";r.push(v)}this.chainCall(r)},chainCall:function(s){var r=this;var t=s.pop();if(typeof t==="undefined"){n.success("All datasets imported");this.modal.hideOrDestroy();return}var u=$.when(t.save({content:t.content,source:t.source})).done(function(v){r.updateProgress();responses.push(v);r.chainCall(s)})},initProgress:function(r){this.progress=0;this.progressStep=r},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(r,v){var t=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){t.push(this.parentElement.parentElement.id)}});var s="/api/libraries/datasets/download/"+v;var u={ldda_ids:t};this.processDownload(s,u,"get")},processDownload:function(s,t,u){if(s&&t){t=typeof t=="string"?t:$.param(t);var r="";$.each(t.split("&"),function(){var v=this.split("=");r+='<input type="hidden" name="'+v[0]+'" value="'+v[1]+'" />'});$('<form action="'+s+'" method="'+(u||"post")+'">'+r+"</form>").appendTo("body").submit().remove();n.info("Your download will begin soon")}},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Create New Folder",body:this.templateNewFolderInModal(),buttons:{Create:function(){r.create_new_folder_event()},Close:function(){r.modal.hideOrDestroy();r.modal=null}}});this.modal.show()},create_new_folder_event:function(){var r=this.serialize_new_folder();if(this.validate_new_folder(r)){var t=new c();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];t.url=t.urlRoot+"/"+current_folder_id;var s=this;t.save(r,{success:function(u){s.modal.hideOrDestroy();n.success("Folder created");s.render({id:current_folder_id})},error:function(){n.error("An error occured :(")}})}else{n.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(r){return r.name!==""}});var a=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"show_library_modal"},initialize:function(){},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; overflow: auto !important; ">');tmpl_array.push("");tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push('<a href="" id="create_new_library_btn" class="btn btn-primary file ">New Library</a>');tmpl_array.push('<table class="table table-condensed">');tmpl_array.push(" <thead>");tmpl_array.push(' <th class="button_heading"></th>');tmpl_array.push(" <th>name</th>");tmpl_array.push(" <th>description</th>");tmpl_array.push(" <th>synopsis</th> ");tmpl_array.push(" <th>model type</th> ");tmpl_array.push(" </thead>");tmpl_array.push(" <tbody>");tmpl_array.push(" <% _.each(libraries, function(library) { %>");tmpl_array.push(" <tr>");tmpl_array.push(' <td><button title="Open this library" type="button" data-id="<%- library.get("root_folder_id") %>" class="btn_open_folder btn btn-default btn-xs">');tmpl_array.push(' <span class="fa fa-folder-open"></span> browse</td>');tmpl_array.push(' <td><%- library.get("name") %></td>');tmpl_array.push(' <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("model_class")) %></td>');tmpl_array.push(" </tr>");tmpl_array.push(" <% }); %>");tmpl_array.push(" </tbody>");tmpl_array.push("</table>");tmpl_array.push("</div>");return tmpl_array.join("")},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")},render:function(){$("#center").css("overflow","auto");var r=this;libraries=new o();libraries.fetch({success:function(s){var t=_.template(r.templateLibraryList(),{libraries:s.models});r.$el.html(t)},error:function(t,s){if(s.statusCode().status===403){n.info("Please log in first. Redirecting to login page in 3s.");setTimeout(r.redirectToLogin,3000)}else{n.error("An error occured. Please try again.")}}})},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},modal:null,show_library_modal:function(s){s.preventDefault();s.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){r.create_new_library_event()},Close:function(){r.modal.hideOrDestroy()}}});this.modal.show()},create_new_library_event:function(){var t=this.serialize_new_library();if(this.validate_new_library(t)){var s=new f();var r=this;s.save(t,{success:function(u){r.modal.hideOrDestroy();r.clear_library_modal();r.render();n.success("Library created")},error:function(){n.error("An error occured :(")}})}else{n.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(r){return r.name!==""}});var g=Backbone.View.extend({folderContentView:null,galaxyLibraryview:null,initialize:function(){folderContentView=new m();galaxyLibraryview=new a();library_router=new q();library_router.on("route:libraries",function(){galaxyLibraryview.render()});library_router.on("route:folder_content",function(r){folderContentView.render({id:r})});library_router.on("route:download",function(r,s){if($("#center").find(":checked").length===0){library_router.navigate("folders/"+r,{trigger:true,replace:true})}else{folderContentView.download(r,s);library_router.navigate("folders/"+r,{trigger:false,replace:true})}});Backbone.history.start({pushState:false})}});return{GalaxyApp:g}});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
4 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/fc65aae7f9a3/
Changeset: fc65aae7f9a3
User: martenson
Date: 2014-01-16 19:37:04
Summary: new packed js
Affected #: 2 files
diff -r dd0bf9c3d0e42246964c8d65785ece1feec6b98e -r fc65aae7f9a3b4ea5f040558e7408837a1d41c07 static/scripts/packed/mvc/visualization/scatterplotControlForm.js
--- /dev/null
+++ b/static/scripts/packed/mvc/visualization/scatterplotControlForm.js
@@ -0,0 +1,1 @@
+var ScatterplotControlForm=Backbone.View.extend(LoggableMixin).extend({className:"scatterplot-control-form",dataLoadDelay:4000,dataLoadSize:5000,loadingIndicatorImage:"loading_small_white_bg.gif",fetchMsg:"Fetching data...",renderMsg:"Rendering...",initialize:function(a){this.log(this+".initialize, attributes:",a);this.dataset=null;this.chartConfig=null;this.chart=null;this.loader=null;this.$dataControl=null;this.$chartControl=null;this.$statsDisplay=null;this.$chartDisplay=null;this.dataFetch=null;this.initializeFromAttributes(a);this.initializeChart(a);this.initializeDataLoader(a)},initializeFromAttributes:function(a){if(!a||!a.dataset){throw ("ScatterplotView requires a dataset")}else{this.dataset=a.dataset}if(jQuery.type(this.dataset.metadata_column_types)==="string"){this.dataset.metadata_column_types=this.dataset.metadata_column_types.split(", ")}this.log("\t dataset:",this.dataset);if(this.dataset.comment_lines&&this.dataset.comment_lines.length){var b=this.dataset.comment_lines[0],c=b.split("\t");if(c.length===this.dataset.metadata_column_types.length){this.possibleHeaders=c}}if(!a.apiDatasetsURL){throw ("ScatterplotView requires a apiDatasetsURL")}else{this.dataURL=a.apiDatasetsURL+"/"+this.dataset.id+"?"}this.log("\t dataURL:",this.dataURL)},initializeChart:function(a){this.chartConfig=a.chartConfig||{};this.log("\t initial chartConfig:",this.chartConfig);this.chart=new TwoVarScatterplot(this.chartConfig);this.chartConfig=this.chart.config},initializeDataLoader:function(b){var a=this;this.loader=new LazyDataLoader({url:null,start:b.start||0,total:b.total||this.dataset.metadata_data_lines,delay:this.dataLoadDelay,size:this.dataLoadSize,buildUrl:function(d,c){return this.url+"&"+jQuery.param({start_val:d,max_vals:c})}});$(this.loader).bind("error",function(e,c,d){a.log("ERROR:",c,d);alert("ERROR fetching data:\n"+c+"\n"+d);a.hideLoadingIndicator()})},render:function(){this.log(this+".render");this.$el.append(ScatterplotControlForm.templates.mainLayout({loadingIndicatorImagePath:galaxy_config.root+"static/images/"+this.loadingIndicatorImage,message:""}));this.$dataControl=this._render_dataControl();this.$chartControl=this._render_chartControl();this.$statsDisplay=this.$el.find(".tab-pane#stats-display");this.$chartDisplay=this._render_chartDisplay();if(this.chartConfig.xColumn&&this.chartConfig.yColumn){this.renderChart()}this.$el.find("[title]").tooltip();return this},_render_dataControl:function(){var b=this,a=[],e=[],c=(this.possibleHeaders&&this.$dataControl)?(this.$dataControl.find("#first-line-header-checkbox").is(":checked")):(false);_.each(this.dataset.metadata_column_types,function(i,g){var h=g+1,f="column "+h;if(b.dataset.metadata_column_names){f=b.dataset.metadata_column_names[g]}else{if(c){f=b.possibleHeaders[g]}}a.push({index:h,name:f});if(i==="int"||i==="float"){e.push({index:h,name:f})}});var d=this.$el.find(".tab-pane#data-control");d.html(ScatterplotControlForm.templates.dataControl({allColumns:a,numericColumns:e,possibleHeaders:(this.possibleHeaders)?(this.possibleHeaders.join(", ")):(""),usePossibleHeaders:c}));if(!this.dataset.metadata_column_names&&this.possibleHeaders){d.find("#first-line-header").show()}d.find("#X-select").val(this.chartConfig.xColumn);d.find("#Y-select").val(this.chartConfig.yColumn);if(this.chartConfig.idColumn!==undefined){d.find("#include-id-checkbox").attr("checked",true).trigger("change");d.find("#ID-select").val(this.chartConfig.idColumn)}return d},_render_chartControl:function(){var a=this,b=this.$el.find(".tab-pane#chart-control"),c={datapointSize:{min:2,max:10,step:1},width:{min:200,max:800,step:20},height:{min:200,max:800,step:20}};b.append(ScatterplotControlForm.templates.chartControl(this.chartConfig));b.find(".numeric-slider-input").each(function(){var f=$(this),e=f.find(".slider-output"),g=f.find(".slider"),h=f.attr("id");function d(){var j=$(this),i=j.slider("value");e.text(i)}g.slider(_.extend(c[h],{value:a.chartConfig[h],change:d,slide:d}))});return b},_render_chartDisplay:function(){var a=this.$el.find(".tab-pane#chart-display");a.append(ScatterplotControlForm.templates.chartDisplay(this.chartConfig));return a},events:{"change #include-id-checkbox":"toggleThirdColumnSelector","change #first-line-header-checkbox":"rerenderDataControl","click #data-control #render-button":"renderChart","click #chart-control #render-button":"changeChartSettings"},toggleThirdColumnSelector:function(){this.$el.find('select[name="ID"]').parent().toggle()},rerenderDataControl:function(){this.$dataControl=this._render_dataControl()},showLoadingIndicator:function(b,c){b=b||"";var a=this.$el.find("div#loading-indicator");messageBox=a.find(".loading-message");if(a.is(":visible")){if(b){messageBox.fadeOut("fast",function(){messageBox.text(b);messageBox.fadeIn("fast",c)})}else{c()}}else{if(b){messageBox.text(b)}a.fadeIn("fast",c)}},hideLoadingIndicator:function(a){this.$el.find("div#loading-indicator").fadeOut("fast",a)},renderChart:function(){this.log(this+".renderChart");this.data=null;this.meta=null;_.extend(this.chartConfig,this.getChartSettings());this.log("\t chartConfig:",this.chartConfig);this.chart.updateConfig(this.chartConfig,false);this.loader.url=this.dataURL+"&"+jQuery.param(this.getDataSettings());this.log("\t loader: total lines:",this.loader.total," url:",this.loader.url);var a=this;$(this.loader).bind("loaded.new",function(c,b){a.log(a+" loaded.new",b);a.postProcessDataFetchResponse(b);a.log("\t postprocessed data:",a.data);a.log("\t postprocessed meta:",a.meta);a.showLoadingIndicator(a.renderMsg,function(){a.chart.render(a.data,a.meta);a.renderStats(a.data,a.meta);a.hideLoadingIndicator()})});$(this.loader).bind("complete",function(b,c){a.log(a+" complete",c);$(a.loader).unbind()});a.showLoadingIndicator(a.fetchMsg,function(){a.$el.find("ul.nav").find('a[href="#chart-display"]').tab("show");a.loader.load()})},renderStats:function(){this.log(this+".renderStats");this.$statsDisplay.html(ScatterplotControlForm.templates.statsDisplay({stats:[{name:"Count",xval:this.meta[0].count,yval:this.meta[1].count},{name:"Min",xval:this.meta[0].min,yval:this.meta[1].min},{name:"Max",xval:this.meta[0].max,yval:this.meta[1].max},{name:"Sum",xval:this.meta[0].sum,yval:this.meta[1].sum},{name:"Mean",xval:this.meta[0].mean,yval:this.meta[1].mean},{name:"Median",xval:this.meta[0].median,yval:this.meta[1].median}]}))},changeChartSettings:function(){var a=this;newChartSettings=this.getChartSettings();_.extend(this.chartConfig,newChartSettings);this.log("this.chartConfig:",this.chartConfig);this.chart.updateConfig(this.chartConfig,false);if(a.data&&a.meta){a.showLoadingIndicator(a.renderMsg,function(){a.$el.find("ul.nav").find('a[href="#chart-display"]').tab("show");a.chart.render(a.data,a.meta);a.hideLoadingIndicator()})}else{this.renderChart()}},postProcessDataFetchResponse:function(a){this.postProcessData(a.data);this.postProcessMeta(a.meta)},postProcessData:function(b){var a=this;if(a.data){_.each(b,function(d,c){a.data[c]=a.data[c].concat(d)})}else{a.data=b}},postProcessMeta:function(c){var a=this,b=this.dataset.metadata_column_types;if(a.meta){_.each(c,function(e,d){var i=a.meta[d],g=b[d];i.count+=(e.count)?(e.count):(0);if((g==="int")||(g==="float")){i.min=Math.min(e.min,i.min);i.max=Math.max(e.max,i.max);i.sum=e.sum+i.sum;i.mean=(i.count)?(i.sum/i.count):(null);var f=a.data[d].slice().sort(),h=Math.floor(f.length/2);if(f.length%2===0){i.median=((f[h]+f[(h+1)])/2)}else{i.median=f[h]}}})}else{a.meta=c}},getDataSettings:function(){var b=this.getColumnSelections(),a=[];this.log("\t columnSelections:",b);a=[b.X.colIndex-1,b.Y.colIndex-1];if(this.$dataControl.find("#include-id-checkbox").attr("checked")){a.push(b.ID.colIndex-1)}var c={data_type:"raw_data",provider:"column_with_stats",columns:"["+a+"]"};this.log("\t data settings (url params):",c);return c},getColumnSelections:function(){var a={};this.$dataControl.find("div.column-select select").each(function(){var b=$(this),c=b.val();a[b.attr("name")]={colIndex:c,colName:b.children('[value="'+c+'"]').text()}});return a},getChartSettings:function(){var c={},d=this.getColumnSelections();c.datapointSize=this.$chartControl.find("#datapointSize.numeric-slider-input").find(".slider").slider("value");c.width=this.$chartControl.find("#width.numeric-slider-input").find(".slider").slider("value");c.height=this.$chartControl.find("#height.numeric-slider-input").find(".slider").slider("value");var b=this.$chartControl.find("input#X-axis-label").val(),a=this.$chartControl.find("input#Y-axis-label").val();c.xLabel=(b==="X")?(d.X.colName):(b);c.yLabel=(a==="Y")?(d.Y.colName):(a);c.animDuration=(this.$chartControl.find("#animate-chart").is(":checked"))?(this.chart.defaults.animDuration):(0);this.log("\t chartSettings:",c);return c},toString:function(){return"ScatterplotControlForm("+((this.dataset)?(this.dataset.id):(""))+")"}});ScatterplotControlForm.templates={mainLayout:Handlebars.templates["template-visualization-scatterplotControlForm"],dataControl:Handlebars.templates["template-visualization-dataControl"],chartControl:Handlebars.templates["template-visualization-chartControl"],statsDisplay:Handlebars.templates["template-visualization-statsDisplay"],chartDisplay:Handlebars.templates["template-visualization-chartDisplay"]};
\ No newline at end of file
diff -r dd0bf9c3d0e42246964c8d65785ece1feec6b98e -r fc65aae7f9a3b4ea5f040558e7408837a1d41c07 static/scripts/packed/mvc/visualization/visualization-model.js
--- /dev/null
+++ b/static/scripts/packed/mvc/visualization/visualization-model.js
@@ -0,0 +1,1 @@
+var Visualization=Backbone.Model.extend(LoggableMixin).extend({defaults:{},url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(a){this.log(this+".initialize",a,this.attributes);this._setUpListeners()},_setUpListeners:function(){},setConfig:function(b){var a=this.get("config");if(_.isObject(a)){b=_.extend(_.clone(a),b)}this.set("config",b);return this},toString:function(){var a=this.get("id")||"";if(this.get("title")){a+=":"+this.get("title")}return"Visualization("+a+")"}});var VisualizationCollection=Backbone.Collection.extend(LoggableMixin).extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(b,a){a=a||{}},set:function(c,a){var b=this;c=_.map(c,function(e){var f=b.get(e.id);if(!f){return e}var d=f.toJSON();_.extend(d,e);return d});Backbone.Collection.prototype.set.call(this,c,a)},toString:function(){return(["VisualizationCollection(",[this.historyId,this.length].join(),")"].join(""))}});
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/commits/9855cc27c607/
Changeset: 9855cc27c607
User: martenson
Date: 2014-01-16 20:08:58
Summary: PEP8 tweaks
Affected #: 1 file
diff -r fc65aae7f9a3b4ea5f040558e7408837a1d41c07 -r 9855cc27c607c9b3889610660259b17d16f3c0c8 lib/galaxy/webapps/galaxy/api/authenticate.py
--- a/lib/galaxy/webapps/galaxy/api/authenticate.py
+++ b/lib/galaxy/webapps/galaxy/api/authenticate.py
@@ -21,19 +21,24 @@
def get_api_key( self, trans, **kwd )
* GET /api/authenticate/baseauth
returns an API key for authenticated user based on BaseAuth headers
+
+ :rtype: dict
+ :returns: api_key in json format
+
+ :raises: ObjectNotFound, HTTPBadRequest
"""
email, password = self._decode_baseauth( trans.environ.get( 'HTTP_AUTHORIZATION' ) )
user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email == email ).all()
- if (len(user) is not 1):
+ if ( len( user ) is not 1 ):
# DB is inconsistent and we have more users with same email
raise ObjectNotFound
else:
user = user[0]
is_valid_user = user.check_password( password )
- if (is_valid_user):
+ if ( is_valid_user ):
user_id = user.id
api_key_row = trans.sa_session.query( trans.app.model.APIKeys ).filter( trans.app.model.APIKeys.table.c.user_id == user_id ).first()
else:
@@ -47,23 +52,23 @@
the form (email, password), and raises a HTTPBadRequest exception if
nothing could be decoded.
"""
- split = encoded_str.strip().split(' ')
+ split = encoded_str.strip().split( ' ' )
# If split is only one element, try to decode the email and password
# directly.
- if len(split) == 1:
+ if len( split ) == 1:
try:
- email, password = b64decode(split[0]).split(':')
+ email, password = b64decode( split[ 0 ] ).split( ':' )
except:
raise HTTPBadRequest
# If there are only two elements, check the first and ensure it says
# 'basic' so that we know we're about to decode the right thing. If not,
# bail out.
- elif len(split) == 2:
- if split[0].strip().lower() == 'basic':
+ elif len( split ) == 2:
+ if split[ 0 ].strip().lower() == 'basic':
try:
- email, password = b64decode(split[1]).split(':')
+ email, password = b64decode( split[ 1 ] ).split( ':' )
except:
raise HTTPBadRequest
else:
@@ -74,4 +79,4 @@
else:
raise HTTPBadRequest
- return unquote(email), unquote(password)
+ return unquote( email ), unquote( password )
https://bitbucket.org/galaxy/galaxy-central/commits/1773a15233bb/
Changeset: 1773a15233bb
User: martenson
Date: 2014-01-16 20:13:15
Summary: Merge
Affected #: 4 files
diff -r 9855cc27c607c9b3889610660259b17d16f3c0c8 -r 1773a15233bb1424f86481068a386d6e0aeaba9e lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -602,7 +602,11 @@
if check_migrate_tools:
# Alert the Galaxy admin to tools that have been moved from the distribution to the tool shed.
from tool_shed.galaxy_install.migrate.check import verify_tools
- verify_tools( self, install_db_url, config_file, self.config.database_engine_options )
+ if combined_install_database:
+ install_database_options = self.config.database_engine_options
+ else:
+ install_database_options = self.config.install_database_engine_options
+ verify_tools( self, install_db_url, config_file, install_database_options )
from galaxy.model import mapping
self.model = mapping.init( self.config.file_path,
diff -r 9855cc27c607c9b3889610660259b17d16f3c0c8 -r 1773a15233bb1424f86481068a386d6e0aeaba9e lib/galaxy/webapps/tool_shed/api/repositories.py
--- a/lib/galaxy/webapps/tool_shed/api/repositories.py
+++ b/lib/galaxy/webapps/tool_shed/api/repositories.py
@@ -129,7 +129,7 @@
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans,
encoded_repository_id,
changeset_revision )
- if not repository_metadata:
+ if repository_metadata is None:
# The changeset_revision column in the repository_metadata table has been updated with a new
# value value, so find the changeset_revision to which we need to update.
repo_dir = repository.repo_path( trans.app )
@@ -139,7 +139,7 @@
encoded_repository_id,
new_changeset_revision )
changeset_revision = new_changeset_revision
- if repository_metadata:
+ if repository_metadata is not None:
encoded_repository_metadata_id = trans.security.encode_id( repository_metadata.id )
repository_metadata_dict = repository_metadata.to_dict( view='collection',
value_mapper=self.__get_value_mapper( trans ) )
@@ -168,7 +168,8 @@
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id,
- 'repository_id' : trans.security.encode_id }
+ 'repository_id' : trans.security.encode_id,
+ 'user_id' : trans.security.encode_id }
return value_mapper
@web.expose_api
diff -r 9855cc27c607c9b3889610660259b17d16f3c0c8 -r 1773a15233bb1424f86481068a386d6e0aeaba9e lib/galaxy/webapps/tool_shed/api/repository_revisions.py
--- a/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
+++ b/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
@@ -68,7 +68,8 @@
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id,
- 'repository_id' : trans.security.encode_id }
+ 'repository_id' : trans.security.encode_id,
+ 'user_id' : trans.security.encode_id }
return value_mapper
@web.expose_api_anonymous
@@ -159,15 +160,33 @@
repository_dependency_repository_metadata = \
suc.get_repository_metadata_by_changeset_revision( trans, repository_dependency_id, changeset_revision )
if repository_dependency_repository_metadata is None:
- log.debug( 'Cannot locate repository_metadata with id %s for repository dependency %s owned by %s.' % \
- ( str( repository_dependency_id ), str( name ), str( owner ) ) )
- continue
+ # The changeset_revision column in the repository_metadata table has been updated with a new
+ # value value, so find the changeset_revision to which we need to update.
+ repo_dir = repository_dependency.repo_path( trans.app )
+ repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository_dependency,
+ repo,
+ changeset_revision )
+ repository_dependency_repository_metadata = \
+ suc.get_repository_metadata_by_changeset_revision( trans,
+ repository_dependency_id,
+ new_changeset_revision )
+ if repository_dependency_repository_metadata is None:
+ decoded_repository_dependency_id = trans.security.decode_id( repository_dependency_id )
+ debug_msg = 'Cannot locate repository_metadata with id %d for repository dependency %s owned by %s ' % \
+ ( decoded_repository_dependency_id, str( name ), str( owner ) )
+ debug_msg += 'using either of these changeset_revisions: %s, %s.' % \
+ ( str( changeset_revision ), str( new_changeset_revision ) )
+ log.debug( debug_msg )
+ continue
+ else:
+ changeset_revision = new_changeset_revision
repository_dependency_repository_metadata_id = trans.security.encode_id( repository_dependency_repository_metadata.id )
repository_dependency_dict = repository_dependency.to_dict( view='element',
value_mapper=self.__get_value_mapper( trans ) )
# We have to add the changeset_revision of of the repository dependency.
repository_dependency_dict[ 'changeset_revision' ] = changeset_revision
- repository_dependency_dict[ 'url' ] = web.url_for( controller='repositories',
+ repository_dependency_dict[ 'url' ] = web.url_for( controller='repository_revisions',
action='show',
id=repository_dependency_repository_metadata_id )
repository_dependencies_dicts.append( repository_dependency_dict )
diff -r 9855cc27c607c9b3889610660259b17d16f3c0c8 -r 1773a15233bb1424f86481068a386d6e0aeaba9e lib/tool_shed/util/shed_util_common.py
--- a/lib/tool_shed/util/shed_util_common.py
+++ b/lib/tool_shed/util/shed_util_common.py
@@ -724,8 +724,8 @@
def get_next_downloadable_changeset_revision( repository, repo, after_changeset_revision ):
"""
- Return the installable changeset_revision in the repository changelog after the changeset to which after_changeset_revision refers. If there
- isn't one, return None.
+ Return the installable changeset_revision in the repository changelog after the changeset to which
+ after_changeset_revision refers. If there isn't one, return None.
"""
changeset_revisions = get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True )
if len( changeset_revisions ) == 1:
https://bitbucket.org/galaxy/galaxy-central/commits/2b0aba01ad8d/
Changeset: 2b0aba01ad8d
User: martenson
Date: 2014-01-17 15:55:27
Summary: Merge
Affected #: 19 files
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -1,10 +1,10 @@
// dependencies
define(['library/portlet', 'library/ui', 'library/utils',
'views/charts', 'views/viewport', 'views/chart', 'views/group',
- 'models/datasets', 'models/chart', 'models/charts', 'models/types'],
+ 'models/config', 'models/datasets', 'models/chart', 'models/charts', 'models/group', 'models/types'],
function( Portlet, Ui, Utils,
ChartsView, ViewportView, ChartView, GroupView,
- Datasets, Chart, Charts, Types
+ Config, Datasets, Chart, Charts, Group, Types
) {
// widget
@@ -19,10 +19,14 @@
// link galaxy
this.modal = parent.Galaxy.modal;
+ // create configuration model
+ this.config = new Config();
+
// create chart models
this.types = new Types();
this.chart = new Chart();
this.charts = new Charts();
+ this.group = new Group();
// create dataset handler
this.datasets = new Datasets(this);
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae config/plugins/visualizations/charts/static/models/chart.js
--- a/config/plugins/visualizations/charts/static/models/chart.js
+++ b/config/plugins/visualizations/charts/static/models/chart.js
@@ -22,8 +22,9 @@
// reset
reset: function()
{
- this.clear().set(this.defaults);
+ this.clear({silent: true}).set(this.defaults);
this.groups.reset();
+ this.trigger('reset', this);
},
// copy
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae config/plugins/visualizations/charts/static/models/config.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/models/config.js
@@ -0,0 +1,16 @@
+// dependencies
+define([], function() {
+
+
+// model
+return Backbone.Model.extend(
+{
+ // options
+ defaults : {
+ query_limit : 20,
+ query_pace : 1000,
+ query_max : 5
+ }
+});
+
+});
\ No newline at end of file
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae config/plugins/visualizations/charts/static/models/group.js
--- a/config/plugins/visualizations/charts/static/models/group.js
+++ b/config/plugins/visualizations/charts/static/models/group.js
@@ -1,23 +1,14 @@
// dependencies
-define(['library/utils'], function(Utils) {
-
+define([], function() {
// model
return Backbone.Model.extend(
{
- // defaults
- defaults : {
- },
-
- // initialize
- initialize: function(options)
- {
- },
-
// reset
reset: function()
{
- this.clear().set(this.defaults);
+ this.clear({silent: true}).set(this.defaults);
+ this.trigger('reset', this);
}
});
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae config/plugins/visualizations/charts/static/views/chart.js
--- a/config/plugins/visualizations/charts/static/views/chart.js
+++ b/config/plugins/visualizations/charts/static/views/chart.js
@@ -125,6 +125,9 @@
this.chart.on('change:type', function(chart) {
self.table.value(chart.get('type'));
});
+ this.chart.on('reset', function(chart) {
+ self._resetChart();
+ });
// collection events
this.app.charts.on('add', function(chart) {
@@ -140,23 +143,17 @@
});
// reset
- this.reset();
+ this._resetChart();
},
// reset
- reset: function() {
- this.chart.reset();
+ _resetChart: function() {
this.chart.set('id', Utils.uuid());
this.chart.set('dataset_id', this.app.options.dataset.id);
this.chart.set('type', 'bardiagram');
this.chart.set('title', 'Chart title');
},
- // set chart
- setChart: function(new_chart) {
- this.chart.copy(new_chart);
- },
-
// create chart
_saveChart: function() {
// update chart data
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae config/plugins/visualizations/charts/static/views/charts.js
--- a/config/plugins/visualizations/charts/static/views/charts.js
+++ b/config/plugins/visualizations/charts/static/views/charts.js
@@ -16,12 +16,12 @@
ondblclick : function(chart_id) {
// get chart
var chart = self.app.charts.get(chart_id);
-
+ self.app.chart.copy(chart);
+
// show edit
self.$el.hide();
// update model and show create
- self.app.chart_view.setChart(chart);
self.app.chart_view.$el.show();
},
onchange : function(chart_id) {
@@ -41,7 +41,7 @@
tooltip: 'Create',
onclick: function() {
self.$el.hide();
- self.app.chart_view.reset();
+ self.app.chart.reset();
self.app.chart_view.$el.show();
}
}),
@@ -57,11 +57,11 @@
// get chart
var chart = self.app.charts.get(chart_id);
+ self.app.chart.copy(chart);
// show edit
self.$el.hide();
self.app.chart_view.$el.show();
- self.app.chart_view.setChart(chart);
}
}),
'delete' : new Ui.ButtonIcon({
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae config/plugins/visualizations/charts/static/views/group.js
--- a/config/plugins/visualizations/charts/static/views/group.js
+++ b/config/plugins/visualizations/charts/static/views/group.js
@@ -1,13 +1,10 @@
// dependencies
-define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/group'],
- function(Portlet, Table, Ui, Utils, Group) {
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils'],
+ function(Portlet, Table, Ui, Utils) {
// chart config
return Backbone.View.extend(
{
- // model
- group: new Group(),
-
// columns
columns: [],
@@ -18,6 +15,7 @@
// get current chart object
this.chart = this.app.chart;
+ this.group = this.app.group;
// ui elements
this.message = new Ui.Message();
@@ -69,6 +67,9 @@
this.group.on('change', function() {
self._refreshGroup();
});
+ this.group.on('reset', function() {
+ self._resetGroup();
+ });
},
// show
@@ -77,8 +78,7 @@
},
// reset
- reset: function() {
- this.group.reset();
+ _resetGroup: function() {
this.group.set('id', Utils.uuid());
this.group.set('label', 'Group label');
},
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae config/plugins/visualizations/charts/static/views/groups.js
--- a/config/plugins/visualizations/charts/static/views/groups.js
+++ b/config/plugins/visualizations/charts/static/views/groups.js
@@ -37,9 +37,9 @@
icon : 'fa-plus',
tooltip: 'Create',
onclick: function() {
+ self.app.group.reset();
self.app.chart_view.$el.hide();
self.app.group_view.show();
- self.app.group_view.reset();
}
}),
'edit' : new Ui.ButtonIcon({
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae lib/galaxy/datatypes/data.py
--- a/lib/galaxy/datatypes/data.py
+++ b/lib/galaxy/datatypes/data.py
@@ -512,13 +512,14 @@
def before_setting_metadata( self, dataset ):
"""This function is called on the dataset before metadata is set."""
dataset.clear_associated_files( metadata_safe = True )
- def __new_composite_file( self, name, optional = False, mimetype = None, description = None, substitute_name_with_metadata = None, is_binary = False, space_to_tab = False, **kwds ):
+ def __new_composite_file( self, name, optional = False, mimetype = None, description = None, substitute_name_with_metadata = None, is_binary = False, to_posix_lines = True, space_to_tab = False, **kwds ):
kwds[ 'name' ] = name
kwds[ 'optional' ] = optional
kwds[ 'mimetype' ] = mimetype
kwds[ 'description' ] = description
kwds[ 'substitute_name_with_metadata' ] = substitute_name_with_metadata
kwds[ 'is_binary' ] = is_binary
+ kwds[ 'to_posix_lines' ] = to_posix_lines
kwds[ 'space_to_tab' ] = space_to_tab
return Bunch( **kwds )
def add_composite_file( self, name, **kwds ):
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae lib/galaxy/tools/actions/upload_common.py
--- a/lib/galaxy/tools/actions/upload_common.py
+++ b/lib/galaxy/tools/actions/upload_common.py
@@ -332,6 +332,7 @@
is_binary=is_binary,
link_data_only=link_data_only,
uuid=uuid_str,
+ to_posix_lines=uploaded_dataset.to_posix_lines,
space_to_tab=uploaded_dataset.space_to_tab,
in_place=trans.app.config.external_chown_script is None,
path=uploaded_dataset.path )
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae lib/galaxy/tools/parameters/grouping.py
--- a/lib/galaxy/tools/parameters/grouping.py
+++ b/lib/galaxy/tools/parameters/grouping.py
@@ -266,6 +266,9 @@
name = context.get( 'NAME', None )
info = context.get( 'INFO', None )
warnings = []
+ to_posix_lines = False
+ if context.get( 'to_posix_lines', None ) not in [ "None", None, False ]:
+ to_posix_lines = True
space_to_tab = False
if context.get( 'space_to_tab', None ) not in [ "None", None, False ]:
space_to_tab = True
@@ -298,6 +301,7 @@
break
if file_bunch.path:
break
+ file_bunch.to_posix_lines = to_posix_lines
file_bunch.space_to_tab = space_to_tab
return file_bunch, warnings
def get_filenames( context ):
@@ -307,16 +311,21 @@
ftp_files = context['ftp_files']
name = context.get( 'NAME', None )
info = context.get( 'INFO', None )
+ to_posix_lines = False
+ if context.get( 'to_posix_lines', None ) not in [ "None", None, False ]:
+ to_posix_lines = True
space_to_tab = False
if context.get( 'space_to_tab', None ) not in [ "None", None, False ]:
space_to_tab = True
warnings = []
file_bunch = get_data_file_filename( data_file, override_name = name, override_info = info )
if file_bunch.path:
+ file_bunch.to_posix_lines = to_posix_lines
file_bunch.space_to_tab = space_to_tab
rval.append( file_bunch )
for file_bunch in get_url_paste_urls_or_filename( context, override_name = name, override_info = info ):
if file_bunch.path:
+ file_bunch.to_posix_lines = to_posix_lines
file_bunch.space_to_tab = space_to_tab
rval.append( file_bunch )
# look for files uploaded via FTP
@@ -390,11 +399,13 @@
#replace sniff here with just creating an empty file
temp_name, is_multi_byte = sniff.stream_to_file( StringIO.StringIO( d_type.generate_primary_file( dataset ) ), prefix='upload_auto_primary_file' )
dataset.primary_file = temp_name
+ dataset.to_posix_lines = True
dataset.space_to_tab = False
else:
file_bunch, warnings = get_one_filename( groups_incoming[ 0 ] )
writable_files_offset = 1
dataset.primary_file = file_bunch.path
+ dataset.to_posix_lines = file_bunch.to_posix_lines
dataset.space_to_tab = file_bunch.space_to_tab
dataset.warnings.extend( warnings )
if dataset.primary_file is None:#remove this before finish, this should create an empty dataset
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae lib/galaxy/webapps/galaxy/api/tool_shed_repositories.py
--- a/lib/galaxy/webapps/galaxy/api/tool_shed_repositories.py
+++ b/lib/galaxy/webapps/galaxy/api/tool_shed_repositories.py
@@ -524,7 +524,7 @@
results[ 'repository_status' ].append( message )
stop_time = strftime( "%Y-%m-%d %H:%M:%S" )
results[ 'stop_time' ] = stop_time
- return json.to_json_string( results, sort_keys=True, indent=4 * ' ' )
+ return json.to_json_string( results, sort_keys=True, indent=4 )
@web.expose_api
def show( self, trans, id, **kwd ):
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae lib/galaxy/webapps/galaxy/api/tools.py
--- a/lib/galaxy/webapps/galaxy/api/tools.py
+++ b/lib/galaxy/webapps/galaxy/api/tools.py
@@ -53,7 +53,7 @@
link_details = util.string_as_bool( kwd.get( 'link_details', False ) )
try:
id = urllib.unquote_plus( id )
- tool = self.app.toolbox.tools_by_id.get( id, None )
+ tool = self.app.toolbox.get_tool( id )
if not tool:
trans.response.status = 404
return { 'error': 'tool not found', 'id': id }
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -129,7 +129,7 @@
webapp.mapper.resource( 'role', 'roles', path_prefix='/api' )
webapp.mapper.resource( 'group', 'groups', path_prefix='/api' )
webapp.mapper.resource_with_deleted( 'quota', 'quotas', path_prefix='/api' )
- webapp.mapper.connect( '/api/tools/{id:.*?}', action='show', controller="tools" )
+ webapp.mapper.connect( '/api/tools/{id:.+?}', action='show', controller="tools" )
webapp.mapper.resource( 'tool', 'tools', path_prefix='/api' )
webapp.mapper.resource_with_deleted( 'user', 'users', path_prefix='/api' )
webapp.mapper.resource( 'genome', 'genomes', path_prefix='/api' )
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae lib/galaxy/webapps/tool_shed/api/repositories.py
--- a/lib/galaxy/webapps/tool_shed/api/repositories.py
+++ b/lib/galaxy/webapps/tool_shed/api/repositories.py
@@ -384,7 +384,7 @@
results = handle_repository( trans, repository, results )
stop_time = strftime( "%Y-%m-%d %H:%M:%S" )
results[ 'stop_time' ] = stop_time
- return json.to_json_string( results, sort_keys=True, indent=4 * ' ' )
+ return json.to_json_string( results, sort_keys=True, indent=4 )
@web.expose_api
def reset_metadata_on_repository( self, trans, payload, **kwd ):
@@ -423,7 +423,7 @@
results = handle_repository( trans, start_time, repository )
stop_time = strftime( "%Y-%m-%d %H:%M:%S" )
results[ 'stop_time' ] = stop_time
- return json.to_json_string( results, sort_keys=True, indent=4 * ' ' )
+ return json.to_json_string( results, sort_keys=True, indent=4 )
@web.expose_api_anonymous
def show( self, trans, id, **kwd ):
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae lib/tool_shed/util/shed_util_common.py
--- a/lib/tool_shed/util/shed_util_common.py
+++ b/lib/tool_shed/util/shed_util_common.py
@@ -877,8 +877,7 @@
username = trans.user.username
clause_list = []
for repository in trans.sa_session.query( trans.model.Repository ) \
- .filter( and_( trans.model.Repository.table.c.deleted == False,
- trans.model.Repository.table.c.deprecated == False ) ):
+ .filter( trans.model.Repository.table.c.deleted == False ):
# Always reset metadata on all repositories of type tool_dependency_definition.
if repository.type == rt_util.TOOL_DEPENDENCY_DEFINITION:
clause_list.append( trans.model.Repository.table.c.id == repository.id )
@@ -905,14 +904,12 @@
else:
if order:
return trans.sa_session.query( trans.model.Repository ) \
- .filter( and_( trans.model.Repository.table.c.deleted == False,
- trans.model.Repository.table.c.deprecated == False ) ) \
+ .filter( trans.model.Repository.table.c.deleted == False ) \
.order_by( trans.model.Repository.table.c.name,
trans.model.Repository.table.c.user_id )
else:
return trans.sa_session.query( trans.model.Repository ) \
- .filter( and_( trans.model.Repository.table.c.deleted == False,
- trans.model.Repository.table.c.deprecated == False ) )
+ .filter( trans.model.Repository.table.c.deleted == False )
else:
# We're in Galaxy.
if order:
@@ -1599,8 +1596,8 @@
return folder_contents
def pretty_print( dict=None ):
- if dict:
- return json.to_json_string( dict, sort_keys=True, indent=4 * ' ' )
+ if dict is not None:
+ return json.to_json_string( dict, sort_keys=True, indent=4 )
def remove_dir( dir ):
"""Attempt to remove a directory from disk."""
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae test/functional/api/test_tools.py
--- a/test/functional/api/test_tools.py
+++ b/test/functional/api/test_tools.py
@@ -33,6 +33,27 @@
create_response = self._post( "tools", data=payload )
self._assert_has_keys( create_response.json(), 'outputs' )
+ def test_upload_posix_newline_fixes( self ):
+ windows_content = "1\t2\t3\r4\t5\t6\r"
+ posix_content = windows_content.replace("\r", "\n")
+ result_content = self._upload_and_get_content( windows_content )
+ self.assertEquals( result_content, posix_content )
+
+ def test_upload_disable_posix_fix( self ):
+ windows_content = "1\t2\t3\r4\t5\t6\r"
+ result_content = self._upload_and_get_content( windows_content, to_posix_lines=None )
+ self.assertEquals( result_content, windows_content )
+
+ def test_upload_tab_to_space( self ):
+ table = "1 2 3\n4 5 6\n"
+ result_content = self._upload_and_get_content( table, space_to_tab="Yes" )
+ self.assertEquals( result_content, "1\t2\t3\n4\t5\t6\n" )
+
+ def test_upload_tab_to_space_off_by_default( self ):
+ table = "1 2 3\n4 5 6\n"
+ result_content = self._upload_and_get_content( table )
+ self.assertEquals( result_content, table )
+
def test_run_cat1( self ):
history_id = self._new_history()
new_dataset = self._new_dataset( history_id )
@@ -52,6 +73,14 @@
self._assert_has_keys( create_response.json(), 'outputs' )
self._wait_for_history( history_id, assert_ok=True )
+ def _upload_and_get_content( self, content, **upload_kwds ):
+ history_id = self._new_history()
+ new_dataset = self._new_dataset( history_id, content=content, **upload_kwds )
+ self._wait_for_history( history_id, assert_ok=True )
+ display_response = self._get( "histories/%s/contents/%s/display" % ( history_id, new_dataset[ "id" ] ) )
+ self._assert_status_code_is( display_response, 200 )
+ return display_response.content
+
def _new_dataset( self, history_id, content='TestData123', **kwds ):
payload = self._upload_payload( history_id, content, **kwds )
run_response = self._post( "tools", data=payload )
@@ -86,6 +115,10 @@
'dbkey': dbkey,
'file_type': file_type,
}
+ if "to_posix_lines" in kwds:
+ upload_params[ "files_0|to_posix_lines"] = kwds[ "to_posix_lines" ]
+ if "space_to_tab" in kwds:
+ upload_params[ "files_0|space_to_tab" ] = kwds[ "space_to_tab" ]
return self._run_tool_payload(
tool_id='upload1',
inputs=upload_params,
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae tools/data_source/upload.py
--- a/tools/data_source/upload.py
+++ b/tools/data_source/upload.py
@@ -264,10 +264,14 @@
if link_data_only == 'copy_files':
if dataset.type in ( 'server_dir', 'path_paste' ) and data_type not in [ 'gzip', 'bz2', 'zip' ]:
in_place = False
- if dataset.space_to_tab:
- line_count, converted_path = sniff.convert_newlines_sep2tabs( dataset.path, in_place=in_place )
- else:
- line_count, converted_path = sniff.convert_newlines( dataset.path, in_place=in_place )
+ # Convert universal line endings to Posix line endings, but allow the user to turn it off,
+ # so that is becomes possible to upload gzip, bz2 or zip files with binary data without
+ # corrupting the content of those files.
+ if dataset.to_posix_lines:
+ if dataset.space_to_tab:
+ line_count, converted_path = sniff.convert_newlines_sep2tabs( dataset.path, in_place=in_place )
+ else:
+ line_count, converted_path = sniff.convert_newlines( dataset.path, in_place=in_place )
if dataset.file_type == 'auto':
ext = sniff.guess_ext( dataset.path, registry.sniff_order )
else:
diff -r 1773a15233bb1424f86481068a386d6e0aeaba9e -r 2b0aba01ad8d5025684c19b33be4a3f1fb5916ae tools/data_source/upload.xml
--- a/tools/data_source/upload.xml
+++ b/tools/data_source/upload.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<tool name="Upload File" id="upload1" version="1.1.3" workflow_compatible="false">
+<tool name="Upload File" id="upload1" version="1.1.4" workflow_compatible="false"><description>
from your computer
</description>
@@ -38,6 +38,12 @@
</param><param name="url_paste" type="text" area="true" size="5x35" label="URL/Text" help="Here you may specify a list of URLs (one per line) or paste the contents of a file."/><param name="ftp_files" type="ftpfile" label="Files uploaded via FTP"/>
+ <!-- Change the following parameter from hidden to select to enable
+ modifying this option via the Web GUI. See Bitbucket pull request
+ 171 for more information. -->
+ <param name="to_posix_lines" type="hidden" display="checkboxes" multiple="True" label="Convert universal line endings to Posix line endings" help="Turn this option off if you upload a gzip, bz2 or zip archive which contains a binary file." value="Yes">
+ <option value="Yes" selected="true">Yes</option>
+ </param><param name="space_to_tab" type="select" display="checkboxes" multiple="True" label="Convert spaces to tabs" help="Use this option if you are entering intervals by hand."><option value="Yes">Yes</option></param>
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
5 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/060677b04984/
Changeset: 060677b04984
Branch: upload_binary_files_archive
User: ghuls
Date: 2013-05-27 20:55:52
Summary: Avoid corruption of binary files embedded in gzip, bz2 and zip archives in the upload tool.
Add an option in the upload tool to disable the conversion of universal
line endings to Posix line endings.
This is useful for avoiding corruption of uploaded files when a binary
file is contained inside a gzip, bz2 and zip archive.
This fixes bug report: https://trello.com/card/issue-with-uploaded-2bit-gz-files/506338ce32ae458f6…
Affected #: 5 files
diff -r 31714646a7b441f34a43748065278a1b08940c3c -r 060677b04984c5d171c34330879507c9edca979e lib/galaxy/datatypes/data.py
--- a/lib/galaxy/datatypes/data.py
+++ b/lib/galaxy/datatypes/data.py
@@ -498,13 +498,14 @@
def before_setting_metadata( self, dataset ):
"""This function is called on the dataset before metadata is set."""
dataset.clear_associated_files( metadata_safe = True )
- def __new_composite_file( self, name, optional = False, mimetype = None, description = None, substitute_name_with_metadata = None, is_binary = False, space_to_tab = False, **kwds ):
+ def __new_composite_file( self, name, optional = False, mimetype = None, description = None, substitute_name_with_metadata = None, is_binary = False, to_posix_lines = True, space_to_tab = False, **kwds ):
kwds[ 'name' ] = name
kwds[ 'optional' ] = optional
kwds[ 'mimetype' ] = mimetype
kwds[ 'description' ] = description
kwds[ 'substitute_name_with_metadata' ] = substitute_name_with_metadata
kwds[ 'is_binary' ] = is_binary
+ kwds[ 'to_posix_lines' ] = to_posix_lines
kwds[ 'space_to_tab' ] = space_to_tab
return Bunch( **kwds )
def add_composite_file( self, name, **kwds ):
diff -r 31714646a7b441f34a43748065278a1b08940c3c -r 060677b04984c5d171c34330879507c9edca979e lib/galaxy/tools/actions/upload_common.py
--- a/lib/galaxy/tools/actions/upload_common.py
+++ b/lib/galaxy/tools/actions/upload_common.py
@@ -307,6 +307,7 @@
is_binary = is_binary,
link_data_only = link_data_only,
uuid = uuid_str,
+ to_posix_lines = uploaded_dataset.to_posix_lines,
space_to_tab = uploaded_dataset.space_to_tab,
in_place = trans.app.config.external_chown_script is None,
path = uploaded_dataset.path )
diff -r 31714646a7b441f34a43748065278a1b08940c3c -r 060677b04984c5d171c34330879507c9edca979e lib/galaxy/tools/parameters/grouping.py
--- a/lib/galaxy/tools/parameters/grouping.py
+++ b/lib/galaxy/tools/parameters/grouping.py
@@ -254,6 +254,9 @@
name = context.get( 'NAME', None )
info = context.get( 'INFO', None )
warnings = []
+ to_posix_lines = False
+ if context.get( 'to_posix_lines', None ) not in [ "None", None, False ]:
+ to_posix_lines = True
space_to_tab = False
if context.get( 'space_to_tab', None ) not in [ "None", None, False ]:
space_to_tab = True
@@ -286,6 +289,7 @@
break
if file_bunch.path:
break
+ file_bunch.to_posix_lines = to_posix_lines
file_bunch.space_to_tab = space_to_tab
return file_bunch, warnings
def get_filenames( context ):
@@ -295,16 +299,21 @@
ftp_files = context['ftp_files']
name = context.get( 'NAME', None )
info = context.get( 'INFO', None )
+ to_posix_lines = False
+ if context.get( 'to_posix_lines', None ) not in [ "None", None, False ]:
+ to_posix_lines = True
space_to_tab = False
if context.get( 'space_to_tab', None ) not in [ "None", None, False ]:
space_to_tab = True
warnings = []
file_bunch = get_data_file_filename( data_file, override_name = name, override_info = info )
if file_bunch.path:
+ file_bunch.to_posix_lines = to_posix_lines
file_bunch.space_to_tab = space_to_tab
rval.append( file_bunch )
for file_bunch in get_url_paste_urls_or_filename( context, override_name = name, override_info = info ):
if file_bunch.path:
+ file_bunch.to_posix_lines = to_posix_lines
file_bunch.space_to_tab = space_to_tab
rval.append( file_bunch )
# look for files uploaded via FTP
@@ -378,11 +387,13 @@
#replace sniff here with just creating an empty file
temp_name, is_multi_byte = sniff.stream_to_file( StringIO.StringIO( d_type.generate_primary_file( dataset ) ), prefix='upload_auto_primary_file' )
dataset.primary_file = temp_name
+ dataset.to_posix_lines = True
dataset.space_to_tab = False
else:
file_bunch, warnings = get_one_filename( groups_incoming[ 0 ] )
writable_files_offset = 1
dataset.primary_file = file_bunch.path
+ dataset.to_posix_lines = file_bunch.to_posix_lines
dataset.space_to_tab = file_bunch.space_to_tab
dataset.warnings.extend( warnings )
if dataset.primary_file is None:#remove this before finish, this should create an empty dataset
diff -r 31714646a7b441f34a43748065278a1b08940c3c -r 060677b04984c5d171c34330879507c9edca979e tools/data_source/upload.py
--- a/tools/data_source/upload.py
+++ b/tools/data_source/upload.py
@@ -264,10 +264,14 @@
if link_data_only == 'copy_files':
if dataset.type in ( 'server_dir', 'path_paste' ) and data_type not in [ 'gzip', 'bz2', 'zip' ]:
in_place = False
- if dataset.space_to_tab:
- line_count, converted_path = sniff.convert_newlines_sep2tabs( dataset.path, in_place=in_place )
- else:
- line_count, converted_path = sniff.convert_newlines( dataset.path, in_place=in_place )
+ # Convert universal line endings to Posix line endings, but allow the user to turn it off,
+ # so that is becomes possible to upload gzip, bz2 or zip files with binary data without
+ # corrupting the content of those files.
+ if dataset.to_posix_lines:
+ if dataset.space_to_tab:
+ line_count, converted_path = sniff.convert_newlines_sep2tabs( dataset.path, in_place=in_place )
+ else:
+ line_count, converted_path = sniff.convert_newlines( dataset.path, in_place=in_place )
if dataset.file_type == 'auto':
ext = sniff.guess_ext( dataset.path, registry.sniff_order )
else:
diff -r 31714646a7b441f34a43748065278a1b08940c3c -r 060677b04984c5d171c34330879507c9edca979e tools/data_source/upload.xml
--- a/tools/data_source/upload.xml
+++ b/tools/data_source/upload.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<tool name="Upload File" id="upload1" version="1.1.3" workflow_compatible="false">
+<tool name="Upload File" id="upload1" version="1.1.4" workflow_compatible="false"><description>
from your computer
</description>
@@ -38,6 +38,9 @@
</param><param name="url_paste" type="text" area="true" size="5x35" label="URL/Text" help="Here you may specify a list of URLs (one per line) or paste the contents of a file."/><param name="ftp_files" type="ftpfile" label="Files uploaded via FTP"/>
+ <param name="to_posix_lines" type="select" display="checkboxes" multiple="True" label="Convert universal line endings to Posix line endings" help="Turn this option off if you upload a gzip, bz2 or zip archive which contains a binary file.">
+ <option value="Yes" selected="true">Yes</option>
+ </param><param name="space_to_tab" type="select" display="checkboxes" multiple="True" label="Convert spaces to tabs" help="Use this option if you are entering intervals by hand."><option value="Yes">Yes</option></param>
https://bitbucket.org/galaxy/galaxy-central/commits/8d69bfa4c4e6/
Changeset: 8d69bfa4c4e6
User: jmchilton
Date: 2014-01-17 06:57:43
Summary: Merge pull request 171.
Affected #: 5 files
diff -r 41cd069aa739f735add1b7c6c4bdb5881dc7ed3b -r 8d69bfa4c4e602acf4c7cda0164d9f5e52876dd4 lib/galaxy/datatypes/data.py
--- a/lib/galaxy/datatypes/data.py
+++ b/lib/galaxy/datatypes/data.py
@@ -512,13 +512,14 @@
def before_setting_metadata( self, dataset ):
"""This function is called on the dataset before metadata is set."""
dataset.clear_associated_files( metadata_safe = True )
- def __new_composite_file( self, name, optional = False, mimetype = None, description = None, substitute_name_with_metadata = None, is_binary = False, space_to_tab = False, **kwds ):
+ def __new_composite_file( self, name, optional = False, mimetype = None, description = None, substitute_name_with_metadata = None, is_binary = False, to_posix_lines = True, space_to_tab = False, **kwds ):
kwds[ 'name' ] = name
kwds[ 'optional' ] = optional
kwds[ 'mimetype' ] = mimetype
kwds[ 'description' ] = description
kwds[ 'substitute_name_with_metadata' ] = substitute_name_with_metadata
kwds[ 'is_binary' ] = is_binary
+ kwds[ 'to_posix_lines' ] = to_posix_lines
kwds[ 'space_to_tab' ] = space_to_tab
return Bunch( **kwds )
def add_composite_file( self, name, **kwds ):
diff -r 41cd069aa739f735add1b7c6c4bdb5881dc7ed3b -r 8d69bfa4c4e602acf4c7cda0164d9f5e52876dd4 lib/galaxy/tools/actions/upload_common.py
--- a/lib/galaxy/tools/actions/upload_common.py
+++ b/lib/galaxy/tools/actions/upload_common.py
@@ -332,6 +332,7 @@
is_binary=is_binary,
link_data_only=link_data_only,
uuid=uuid_str,
+ to_posix_lines=uploaded_dataset.to_posix_lines,
space_to_tab=uploaded_dataset.space_to_tab,
in_place=trans.app.config.external_chown_script is None,
path=uploaded_dataset.path )
diff -r 41cd069aa739f735add1b7c6c4bdb5881dc7ed3b -r 8d69bfa4c4e602acf4c7cda0164d9f5e52876dd4 lib/galaxy/tools/parameters/grouping.py
--- a/lib/galaxy/tools/parameters/grouping.py
+++ b/lib/galaxy/tools/parameters/grouping.py
@@ -266,6 +266,9 @@
name = context.get( 'NAME', None )
info = context.get( 'INFO', None )
warnings = []
+ to_posix_lines = False
+ if context.get( 'to_posix_lines', None ) not in [ "None", None, False ]:
+ to_posix_lines = True
space_to_tab = False
if context.get( 'space_to_tab', None ) not in [ "None", None, False ]:
space_to_tab = True
@@ -298,6 +301,7 @@
break
if file_bunch.path:
break
+ file_bunch.to_posix_lines = to_posix_lines
file_bunch.space_to_tab = space_to_tab
return file_bunch, warnings
def get_filenames( context ):
@@ -307,16 +311,21 @@
ftp_files = context['ftp_files']
name = context.get( 'NAME', None )
info = context.get( 'INFO', None )
+ to_posix_lines = False
+ if context.get( 'to_posix_lines', None ) not in [ "None", None, False ]:
+ to_posix_lines = True
space_to_tab = False
if context.get( 'space_to_tab', None ) not in [ "None", None, False ]:
space_to_tab = True
warnings = []
file_bunch = get_data_file_filename( data_file, override_name = name, override_info = info )
if file_bunch.path:
+ file_bunch.to_posix_lines = to_posix_lines
file_bunch.space_to_tab = space_to_tab
rval.append( file_bunch )
for file_bunch in get_url_paste_urls_or_filename( context, override_name = name, override_info = info ):
if file_bunch.path:
+ file_bunch.to_posix_lines = to_posix_lines
file_bunch.space_to_tab = space_to_tab
rval.append( file_bunch )
# look for files uploaded via FTP
@@ -390,11 +399,13 @@
#replace sniff here with just creating an empty file
temp_name, is_multi_byte = sniff.stream_to_file( StringIO.StringIO( d_type.generate_primary_file( dataset ) ), prefix='upload_auto_primary_file' )
dataset.primary_file = temp_name
+ dataset.to_posix_lines = True
dataset.space_to_tab = False
else:
file_bunch, warnings = get_one_filename( groups_incoming[ 0 ] )
writable_files_offset = 1
dataset.primary_file = file_bunch.path
+ dataset.to_posix_lines = file_bunch.to_posix_lines
dataset.space_to_tab = file_bunch.space_to_tab
dataset.warnings.extend( warnings )
if dataset.primary_file is None:#remove this before finish, this should create an empty dataset
diff -r 41cd069aa739f735add1b7c6c4bdb5881dc7ed3b -r 8d69bfa4c4e602acf4c7cda0164d9f5e52876dd4 tools/data_source/upload.py
--- a/tools/data_source/upload.py
+++ b/tools/data_source/upload.py
@@ -264,10 +264,14 @@
if link_data_only == 'copy_files':
if dataset.type in ( 'server_dir', 'path_paste' ) and data_type not in [ 'gzip', 'bz2', 'zip' ]:
in_place = False
- if dataset.space_to_tab:
- line_count, converted_path = sniff.convert_newlines_sep2tabs( dataset.path, in_place=in_place )
- else:
- line_count, converted_path = sniff.convert_newlines( dataset.path, in_place=in_place )
+ # Convert universal line endings to Posix line endings, but allow the user to turn it off,
+ # so that is becomes possible to upload gzip, bz2 or zip files with binary data without
+ # corrupting the content of those files.
+ if dataset.to_posix_lines:
+ if dataset.space_to_tab:
+ line_count, converted_path = sniff.convert_newlines_sep2tabs( dataset.path, in_place=in_place )
+ else:
+ line_count, converted_path = sniff.convert_newlines( dataset.path, in_place=in_place )
if dataset.file_type == 'auto':
ext = sniff.guess_ext( dataset.path, registry.sniff_order )
else:
diff -r 41cd069aa739f735add1b7c6c4bdb5881dc7ed3b -r 8d69bfa4c4e602acf4c7cda0164d9f5e52876dd4 tools/data_source/upload.xml
--- a/tools/data_source/upload.xml
+++ b/tools/data_source/upload.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
-<tool name="Upload File" id="upload1" version="1.1.3" workflow_compatible="false">
+<tool name="Upload File" id="upload1" version="1.1.4" workflow_compatible="false"><description>
from your computer
</description>
@@ -38,6 +38,9 @@
</param><param name="url_paste" type="text" area="true" size="5x35" label="URL/Text" help="Here you may specify a list of URLs (one per line) or paste the contents of a file."/><param name="ftp_files" type="ftpfile" label="Files uploaded via FTP"/>
+ <param name="to_posix_lines" type="select" display="checkboxes" multiple="True" label="Convert universal line endings to Posix line endings" help="Turn this option off if you upload a gzip, bz2 or zip archive which contains a binary file.">
+ <option value="Yes" selected="true">Yes</option>
+ </param><param name="space_to_tab" type="select" display="checkboxes" multiple="True" label="Convert spaces to tabs" help="Use this option if you are entering intervals by hand."><option value="Yes">Yes</option></param>
https://bitbucket.org/galaxy/galaxy-central/commits/daeb94f97da7/
Changeset: daeb94f97da7
Branch: upload_binary_files_archive
User: jmchilton
Date: 2014-01-17 06:58:44
Summary: Close branch upload_binary_files_archive.
Affected #: 0 files
https://bitbucket.org/galaxy/galaxy-central/commits/9acf83083258/
Changeset: 9acf83083258
User: jmchilton
Date: 2014-01-17 07:03:26
Summary: Functionally test various upload options via API.
Affected #: 1 file
diff -r 8d69bfa4c4e602acf4c7cda0164d9f5e52876dd4 -r 9acf83083258e6b6c9ea867aed97281b27991d0a test/functional/api/test_tools.py
--- a/test/functional/api/test_tools.py
+++ b/test/functional/api/test_tools.py
@@ -33,6 +33,27 @@
create_response = self._post( "tools", data=payload )
self._assert_has_keys( create_response.json(), 'outputs' )
+ def test_upload_posix_newline_fixes( self ):
+ windows_content = "1\t2\t3\r4\t5\t6\r"
+ posix_content = windows_content.replace("\r", "\n")
+ result_content = self._upload_and_get_content( windows_content )
+ self.assertEquals( result_content, posix_content )
+
+ def test_upload_disable_posix_fix( self ):
+ windows_content = "1\t2\t3\r4\t5\t6\r"
+ result_content = self._upload_and_get_content( windows_content, to_posix_lines=None )
+ self.assertEquals( result_content, windows_content )
+
+ def test_upload_tab_to_space( self ):
+ table = "1 2 3\n4 5 6\n"
+ result_content = self._upload_and_get_content( table, space_to_tab="Yes" )
+ self.assertEquals( result_content, "1\t2\t3\n4\t5\t6\n" )
+
+ def test_upload_tab_to_space_off_by_default( self ):
+ table = "1 2 3\n4 5 6\n"
+ result_content = self._upload_and_get_content( table )
+ self.assertEquals( result_content, table )
+
def test_run_cat1( self ):
history_id = self._new_history()
new_dataset = self._new_dataset( history_id )
@@ -52,6 +73,14 @@
self._assert_has_keys( create_response.json(), 'outputs' )
self._wait_for_history( history_id, assert_ok=True )
+ def _upload_and_get_content( self, content, **upload_kwds ):
+ history_id = self._new_history()
+ new_dataset = self._new_dataset( history_id, content=content, **upload_kwds )
+ self._wait_for_history( history_id, assert_ok=True )
+ display_response = self._get( "histories/%s/contents/%s/display" % ( history_id, new_dataset[ "id" ] ) )
+ self._assert_status_code_is( display_response, 200 )
+ return display_response.content
+
def _new_dataset( self, history_id, content='TestData123', **kwds ):
payload = self._upload_payload( history_id, content, **kwds )
run_response = self._post( "tools", data=payload )
@@ -86,6 +115,10 @@
'dbkey': dbkey,
'file_type': file_type,
}
+ if "to_posix_lines" in kwds:
+ upload_params[ "files_0|to_posix_lines"] = kwds[ "to_posix_lines" ]
+ if "space_to_tab" in kwds:
+ upload_params[ "files_0|space_to_tab" ] = kwds[ "space_to_tab" ]
return self._run_tool_payload(
tool_id='upload1',
inputs=upload_params,
https://bitbucket.org/galaxy/galaxy-central/commits/b1121a315205/
Changeset: b1121a315205
User: jmchilton
Date: 2014-01-17 07:03:26
Summary: Hide to_posix_lines in UI by default.
Galaxy still completely supports this option on backend - API tests still completely work and will hopefully ensure this functionality continues running. Any Galaxy deployements that wish to enable this option simply have to switch this one param from hidden to select. This is a ugly workaround - but it is a very small workaround - and will hopefully alleviate any potential fears Gert Hulselmans has of Galaxy diverging from his changes. This is only a stop gap until the Galaxy upload UI supports more advanced options.
I have previously outlined my concerns with the visual clutter on the upload.xml page - this is why I am hiding it by default. If anyone with commit access disagrees - please by all means backout of this individual changeset and restore the full functionality of pull request 171 (I have a terrible eye for this sort of GUI design stuff).
Affected #: 1 file
diff -r 9acf83083258e6b6c9ea867aed97281b27991d0a -r b1121a315205e8152d9c59199443c492340e9f0b tools/data_source/upload.xml
--- a/tools/data_source/upload.xml
+++ b/tools/data_source/upload.xml
@@ -38,7 +38,10 @@
</param><param name="url_paste" type="text" area="true" size="5x35" label="URL/Text" help="Here you may specify a list of URLs (one per line) or paste the contents of a file."/><param name="ftp_files" type="ftpfile" label="Files uploaded via FTP"/>
- <param name="to_posix_lines" type="select" display="checkboxes" multiple="True" label="Convert universal line endings to Posix line endings" help="Turn this option off if you upload a gzip, bz2 or zip archive which contains a binary file.">
+ <!-- Change the following parameter from hidden to select to enable
+ modifying this option via the Web GUI. See Bitbucket pull request
+ 171 for more information. -->
+ <param name="to_posix_lines" type="hidden" display="checkboxes" multiple="True" label="Convert universal line endings to Posix line endings" help="Turn this option off if you upload a gzip, bz2 or zip archive which contains a binary file." value="Yes"><option value="Yes" selected="true">Yes</option></param><param name="space_to_tab" type="select" display="checkboxes" multiple="True" label="Convert spaces to tabs" help="Use this option if you are entering intervals by hand.">
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dan: Fix for api/tools/show/ when no id is provided.
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/41cd069aa739/
Changeset: 41cd069aa739
User: dan
Date: 2014-01-16 22:52:39
Summary: Fix for api/tools/show/ when no id is provided.
Affected #: 1 file
diff -r 71186fb4b179fc051e6919dd0e31e94f9cedc3d6 -r 41cd069aa739f735add1b7c6c4bdb5881dc7ed3b lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -129,7 +129,7 @@
webapp.mapper.resource( 'role', 'roles', path_prefix='/api' )
webapp.mapper.resource( 'group', 'groups', path_prefix='/api' )
webapp.mapper.resource_with_deleted( 'quota', 'quotas', path_prefix='/api' )
- webapp.mapper.connect( '/api/tools/{id:.*?}', action='show', controller="tools" )
+ webapp.mapper.connect( '/api/tools/{id:.+?}', action='show', controller="tools" )
webapp.mapper.resource( 'tool', 'tools', path_prefix='/api' )
webapp.mapper.resource_with_deleted( 'user', 'users', path_prefix='/api' )
webapp.mapper.resource( 'genome', 'genomes', path_prefix='/api' )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/71186fb4b179/
Changeset: 71186fb4b179
User: dan
Date: 2014-01-16 22:21:41
Summary: Use toolbox.get_tool instead of toolbox.tools_by_id.get in tools api show().
Affected #: 1 file
diff -r 40a5f3139ecf714090347612ec69e0d964911d85 -r 71186fb4b179fc051e6919dd0e31e94f9cedc3d6 lib/galaxy/webapps/galaxy/api/tools.py
--- a/lib/galaxy/webapps/galaxy/api/tools.py
+++ b/lib/galaxy/webapps/galaxy/api/tools.py
@@ -53,7 +53,7 @@
link_details = util.string_as_bool( kwd.get( 'link_details', False ) )
try:
id = urllib.unquote_plus( id )
- tool = self.app.toolbox.tools_by_id.get( id, None )
+ tool = self.app.toolbox.get_tool( id )
if not tool:
trans.response.status = 404
return { 'error': 'tool not found', 'id': id }
https://bitbucket.org/galaxy/galaxy-central/commits/b2e473cd17cd/
Changeset: b2e473cd17cd
Branch: stable
User: dan
Date: 2014-01-16 22:21:41
Summary: Use toolbox.get_tool instead of toolbox.tools_by_id.get in tools api show().
Affected #: 1 file
diff -r 4e280310697b806aa0e08c80f342e2c93f1558f0 -r b2e473cd17cdd0e5758cee32e74f9be7723658bf lib/galaxy/webapps/galaxy/api/tools.py
--- a/lib/galaxy/webapps/galaxy/api/tools.py
+++ b/lib/galaxy/webapps/galaxy/api/tools.py
@@ -50,7 +50,7 @@
link_details = util.string_as_bool( kwd.get( 'link_details', False ) )
try:
id = urllib.unquote_plus( id )
- tool = self.app.toolbox.tools_by_id.get( id, None )
+ tool = self.app.toolbox.get_tool( id )
if not tool:
trans.response.status = 404
return { 'error': 'tool not found', 'id': id }
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Forgot None in my last commit
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/40a5f3139ecf/
Changeset: 40a5f3139ecf
User: greg
Date: 2014-01-16 22:13:47
Summary: Forgot None in my last commit
Affected #: 1 file
diff -r 56492a1d0d352db016e7ba785fcbc9822b604d61 -r 40a5f3139ecf714090347612ec69e0d964911d85 lib/tool_shed/util/shed_util_common.py
--- a/lib/tool_shed/util/shed_util_common.py
+++ b/lib/tool_shed/util/shed_util_common.py
@@ -1596,7 +1596,7 @@
return folder_contents
def pretty_print( dict=None ):
- if dict is not:
+ if dict is not None:
return json.to_json_string( dict, sort_keys=True, indent=4 )
def remove_dir( dir ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Re-include deprecated repositories when resetting metadata since they can be dependencies of installable repositories.
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/56492a1d0d35/
Changeset: 56492a1d0d35
User: greg
Date: 2014-01-16 22:02:39
Summary: Re-include deprecated repositories when resetting metadata since they can be dependencies of installable repositories.
Affected #: 3 files
diff -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 -r 56492a1d0d352db016e7ba785fcbc9822b604d61 lib/galaxy/webapps/galaxy/api/tool_shed_repositories.py
--- a/lib/galaxy/webapps/galaxy/api/tool_shed_repositories.py
+++ b/lib/galaxy/webapps/galaxy/api/tool_shed_repositories.py
@@ -524,7 +524,7 @@
results[ 'repository_status' ].append( message )
stop_time = strftime( "%Y-%m-%d %H:%M:%S" )
results[ 'stop_time' ] = stop_time
- return json.to_json_string( results, sort_keys=True, indent=4 * ' ' )
+ return json.to_json_string( results, sort_keys=True, indent=4 )
@web.expose_api
def show( self, trans, id, **kwd ):
diff -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 -r 56492a1d0d352db016e7ba785fcbc9822b604d61 lib/galaxy/webapps/tool_shed/api/repositories.py
--- a/lib/galaxy/webapps/tool_shed/api/repositories.py
+++ b/lib/galaxy/webapps/tool_shed/api/repositories.py
@@ -384,7 +384,7 @@
results = handle_repository( trans, repository, results )
stop_time = strftime( "%Y-%m-%d %H:%M:%S" )
results[ 'stop_time' ] = stop_time
- return json.to_json_string( results, sort_keys=True, indent=4 * ' ' )
+ return json.to_json_string( results, sort_keys=True, indent=4 )
@web.expose_api
def reset_metadata_on_repository( self, trans, payload, **kwd ):
@@ -423,7 +423,7 @@
results = handle_repository( trans, start_time, repository )
stop_time = strftime( "%Y-%m-%d %H:%M:%S" )
results[ 'stop_time' ] = stop_time
- return json.to_json_string( results, sort_keys=True, indent=4 * ' ' )
+ return json.to_json_string( results, sort_keys=True, indent=4 )
@web.expose_api_anonymous
def show( self, trans, id, **kwd ):
diff -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 -r 56492a1d0d352db016e7ba785fcbc9822b604d61 lib/tool_shed/util/shed_util_common.py
--- a/lib/tool_shed/util/shed_util_common.py
+++ b/lib/tool_shed/util/shed_util_common.py
@@ -877,8 +877,7 @@
username = trans.user.username
clause_list = []
for repository in trans.sa_session.query( trans.model.Repository ) \
- .filter( and_( trans.model.Repository.table.c.deleted == False,
- trans.model.Repository.table.c.deprecated == False ) ):
+ .filter( trans.model.Repository.table.c.deleted == False ):
# Always reset metadata on all repositories of type tool_dependency_definition.
if repository.type == rt_util.TOOL_DEPENDENCY_DEFINITION:
clause_list.append( trans.model.Repository.table.c.id == repository.id )
@@ -905,14 +904,12 @@
else:
if order:
return trans.sa_session.query( trans.model.Repository ) \
- .filter( and_( trans.model.Repository.table.c.deleted == False,
- trans.model.Repository.table.c.deprecated == False ) ) \
+ .filter( trans.model.Repository.table.c.deleted == False ) \
.order_by( trans.model.Repository.table.c.name,
trans.model.Repository.table.c.user_id )
else:
return trans.sa_session.query( trans.model.Repository ) \
- .filter( and_( trans.model.Repository.table.c.deleted == False,
- trans.model.Repository.table.c.deprecated == False ) )
+ .filter( trans.model.Repository.table.c.deleted == False )
else:
# We're in Galaxy.
if order:
@@ -1599,8 +1596,8 @@
return folder_contents
def pretty_print( dict=None ):
- if dict:
- return json.to_json_string( dict, sort_keys=True, indent=4 * ' ' )
+ if dict is not:
+ return json.to_json_string( dict, sort_keys=True, indent=4 )
def remove_dir( dir ):
"""Attempt to remove a directory from disk."""
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/b76dd608c500/
Changeset: b76dd608c500
User: guerler
Date: 2014-01-16 20:10:32
Summary: Charts: Add configuration model, link all view functions to model events
Affected #: 8 files
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -1,10 +1,10 @@
// dependencies
define(['library/portlet', 'library/ui', 'library/utils',
'views/charts', 'views/viewport', 'views/chart', 'views/group',
- 'models/datasets', 'models/chart', 'models/charts', 'models/types'],
+ 'models/config', 'models/datasets', 'models/chart', 'models/charts', 'models/group', 'models/types'],
function( Portlet, Ui, Utils,
ChartsView, ViewportView, ChartView, GroupView,
- Datasets, Chart, Charts, Types
+ Config, Datasets, Chart, Charts, Group, Types
) {
// widget
@@ -19,10 +19,14 @@
// link galaxy
this.modal = parent.Galaxy.modal;
+ // create configuration model
+ this.config = new Config();
+
// create chart models
this.types = new Types();
this.chart = new Chart();
this.charts = new Charts();
+ this.group = new Group();
// create dataset handler
this.datasets = new Datasets(this);
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/models/chart.js
--- a/config/plugins/visualizations/charts/static/models/chart.js
+++ b/config/plugins/visualizations/charts/static/models/chart.js
@@ -22,8 +22,9 @@
// reset
reset: function()
{
- this.clear().set(this.defaults);
+ this.clear({silent: true}).set(this.defaults);
this.groups.reset();
+ this.trigger('reset', this);
},
// copy
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/models/config.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/models/config.js
@@ -0,0 +1,16 @@
+// dependencies
+define([], function() {
+
+
+// model
+return Backbone.Model.extend(
+{
+ // options
+ defaults : {
+ query_limit : 20,
+ query_pace : 1000,
+ query_max : 5
+ }
+});
+
+});
\ No newline at end of file
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/models/group.js
--- a/config/plugins/visualizations/charts/static/models/group.js
+++ b/config/plugins/visualizations/charts/static/models/group.js
@@ -1,23 +1,14 @@
// dependencies
-define(['library/utils'], function(Utils) {
-
+define([], function() {
// model
return Backbone.Model.extend(
{
- // defaults
- defaults : {
- },
-
- // initialize
- initialize: function(options)
- {
- },
-
// reset
reset: function()
{
- this.clear().set(this.defaults);
+ this.clear({silent: true}).set(this.defaults);
+ this.trigger('reset', this);
}
});
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/views/chart.js
--- a/config/plugins/visualizations/charts/static/views/chart.js
+++ b/config/plugins/visualizations/charts/static/views/chart.js
@@ -125,6 +125,9 @@
this.chart.on('change:type', function(chart) {
self.table.value(chart.get('type'));
});
+ this.chart.on('reset', function(chart) {
+ self._resetChart();
+ });
// collection events
this.app.charts.on('add', function(chart) {
@@ -140,23 +143,17 @@
});
// reset
- this.reset();
+ this._resetChart();
},
// reset
- reset: function() {
- this.chart.reset();
+ _resetChart: function() {
this.chart.set('id', Utils.uuid());
this.chart.set('dataset_id', this.app.options.dataset.id);
this.chart.set('type', 'bardiagram');
this.chart.set('title', 'Chart title');
},
- // set chart
- setChart: function(new_chart) {
- this.chart.copy(new_chart);
- },
-
// create chart
_saveChart: function() {
// update chart data
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/views/charts.js
--- a/config/plugins/visualizations/charts/static/views/charts.js
+++ b/config/plugins/visualizations/charts/static/views/charts.js
@@ -16,12 +16,12 @@
ondblclick : function(chart_id) {
// get chart
var chart = self.app.charts.get(chart_id);
-
+ self.app.chart.copy(chart);
+
// show edit
self.$el.hide();
// update model and show create
- self.app.chart_view.setChart(chart);
self.app.chart_view.$el.show();
},
onchange : function(chart_id) {
@@ -41,7 +41,7 @@
tooltip: 'Create',
onclick: function() {
self.$el.hide();
- self.app.chart_view.reset();
+ self.app.chart.reset();
self.app.chart_view.$el.show();
}
}),
@@ -57,11 +57,11 @@
// get chart
var chart = self.app.charts.get(chart_id);
+ self.app.chart.copy(chart);
// show edit
self.$el.hide();
self.app.chart_view.$el.show();
- self.app.chart_view.setChart(chart);
}
}),
'delete' : new Ui.ButtonIcon({
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/views/group.js
--- a/config/plugins/visualizations/charts/static/views/group.js
+++ b/config/plugins/visualizations/charts/static/views/group.js
@@ -1,13 +1,10 @@
// dependencies
-define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/group'],
- function(Portlet, Table, Ui, Utils, Group) {
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils'],
+ function(Portlet, Table, Ui, Utils) {
// chart config
return Backbone.View.extend(
{
- // model
- group: new Group(),
-
// columns
columns: [],
@@ -18,6 +15,7 @@
// get current chart object
this.chart = this.app.chart;
+ this.group = this.app.group;
// ui elements
this.message = new Ui.Message();
@@ -69,6 +67,9 @@
this.group.on('change', function() {
self._refreshGroup();
});
+ this.group.on('reset', function() {
+ self._resetGroup();
+ });
},
// show
@@ -77,8 +78,7 @@
},
// reset
- reset: function() {
- this.group.reset();
+ _resetGroup: function() {
this.group.set('id', Utils.uuid());
this.group.set('label', 'Group label');
},
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r b76dd608c500d8421d0ec51f6b638b7324ecead6 config/plugins/visualizations/charts/static/views/groups.js
--- a/config/plugins/visualizations/charts/static/views/groups.js
+++ b/config/plugins/visualizations/charts/static/views/groups.js
@@ -37,9 +37,9 @@
icon : 'fa-plus',
tooltip: 'Create',
onclick: function() {
+ self.app.group.reset();
self.app.chart_view.$el.hide();
self.app.group_view.show();
- self.app.group_view.reset();
}
}),
'edit' : new Ui.ButtonIcon({
https://bitbucket.org/galaxy/galaxy-central/commits/dec86d2bd3b1/
Changeset: dec86d2bd3b1
User: guerler
Date: 2014-01-16 20:10:56
Summary: Merge
Affected #: 8 files
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -602,7 +602,11 @@
if check_migrate_tools:
# Alert the Galaxy admin to tools that have been moved from the distribution to the tool shed.
from tool_shed.galaxy_install.migrate.check import verify_tools
- verify_tools( self, install_db_url, config_file, self.config.database_engine_options )
+ if combined_install_database:
+ install_database_options = self.config.database_engine_options
+ else:
+ install_database_options = self.config.install_database_engine_options
+ verify_tools( self, install_db_url, config_file, install_database_options )
from galaxy.model import mapping
self.model = mapping.init( self.config.file_path,
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -734,8 +734,7 @@
self.tags = []
def _next_hid( self ):
- # TODO: override this with something in the database that ensures
- # better integrity
+ # this is overriden in mapping.py db_next_hid() method
if len( self.datasets ) == 0:
return 1
else:
@@ -3446,4 +3445,7 @@
self.context = context
class APIKeys( object ):
- pass
+ def __init__( self, id=None, user_id=None, key=None):
+ self.id = id
+ self.user_id = user_id
+ self.key = key
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/webapps/galaxy/api/authenticate.py
--- /dev/null
+++ b/lib/galaxy/webapps/galaxy/api/authenticate.py
@@ -0,0 +1,77 @@
+"""
+API key retrieval through BaseAuth
+"""
+
+from galaxy import util, web
+from pprint import pprint
+from galaxy.web.base.controller import BaseAPIController
+from base64 import b64decode, b64encode
+from urllib import quote, unquote
+from galaxy.exceptions import ObjectNotFound
+from paste.httpexceptions import HTTPBadRequest
+
+import logging
+log = logging.getLogger( __name__ )
+
+class AuthenticationController( BaseAPIController ):
+
+ @web.expose_api_anonymous
+ def get_api_key( self, trans, **kwd ):
+ """
+ def get_api_key( self, trans, **kwd )
+ * GET /api/authenticate/baseauth
+ returns an API key for authenticated user based on BaseAuth headers
+ """
+ email, password = self._decode_baseauth( trans.environ.get( 'HTTP_AUTHORIZATION' ) )
+
+ user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email == email ).all()
+
+ if (len(user) is not 1):
+ # DB is inconsistent and we have more users with same email
+ raise ObjectNotFound
+ else:
+ user = user[0]
+ is_valid_user = user.check_password( password )
+
+ if (is_valid_user):
+ user_id = user.id
+ api_key_row = trans.sa_session.query( trans.app.model.APIKeys ).filter( trans.app.model.APIKeys.table.c.user_id == user_id ).first()
+ else:
+ trans.response.status = 500
+ return "invalid password"
+
+ return dict( api_key= api_key_row.key )
+
+ def _decode_baseauth( self, encoded_str ):
+ """Decode an encrypted HTTP basic authentication string. Returns a tuple of
+ the form (email, password), and raises a HTTPBadRequest exception if
+ nothing could be decoded.
+ """
+ split = encoded_str.strip().split(' ')
+
+ # If split is only one element, try to decode the email and password
+ # directly.
+ if len(split) == 1:
+ try:
+ email, password = b64decode(split[0]).split(':')
+ except:
+ raise HTTPBadRequest
+
+ # If there are only two elements, check the first and ensure it says
+ # 'basic' so that we know we're about to decode the right thing. If not,
+ # bail out.
+ elif len(split) == 2:
+ if split[0].strip().lower() == 'basic':
+ try:
+ email, password = b64decode(split[1]).split(':')
+ except:
+ raise HTTPBadRequest
+ else:
+ raise HTTPBadRequest
+
+ # If there are more than 2 elements, something crazy must be happening.
+ # Bail.
+ else:
+ raise HTTPBadRequest
+
+ return unquote(email), unquote(password)
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/webapps/galaxy/api/lda_datasets.py
--- a/lib/galaxy/webapps/galaxy/api/lda_datasets.py
+++ b/lib/galaxy/webapps/galaxy/api/lda_datasets.py
@@ -2,7 +2,6 @@
API operations on the datasets from library.
"""
import glob
-import logging
import operator
import os
import os.path
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -169,6 +169,16 @@
webapp.mapper.connect( 'workflow_dict', '/api/workflows/download/{workflow_id}', controller='workflows', action='workflow_dict', conditions=dict( method=['GET'] ) )
webapp.mapper.connect( 'import_shared_workflow', '/api/workflows/import', controller='workflows', action='import_shared_worflow', conditions=dict( method=['POST'] ) )
+ # ============================
+ # ===== AUTHENTICATE API =====
+ # ============================
+
+ webapp.mapper.connect( 'api_key_retrieval',
+ '/api/authenticate/baseauth/',
+ controller='authenticate',
+ action='get_api_key',
+ conditions=dict( method=[ "GET" ] ) )
+
# =======================
# ===== LIBRARY API =====
# =======================
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/webapps/tool_shed/api/repositories.py
--- a/lib/galaxy/webapps/tool_shed/api/repositories.py
+++ b/lib/galaxy/webapps/tool_shed/api/repositories.py
@@ -129,7 +129,7 @@
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans,
encoded_repository_id,
changeset_revision )
- if not repository_metadata:
+ if repository_metadata is None:
# The changeset_revision column in the repository_metadata table has been updated with a new
# value value, so find the changeset_revision to which we need to update.
repo_dir = repository.repo_path( trans.app )
@@ -139,7 +139,7 @@
encoded_repository_id,
new_changeset_revision )
changeset_revision = new_changeset_revision
- if repository_metadata:
+ if repository_metadata is not None:
encoded_repository_metadata_id = trans.security.encode_id( repository_metadata.id )
repository_metadata_dict = repository_metadata.to_dict( view='collection',
value_mapper=self.__get_value_mapper( trans ) )
@@ -168,7 +168,8 @@
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id,
- 'repository_id' : trans.security.encode_id }
+ 'repository_id' : trans.security.encode_id,
+ 'user_id' : trans.security.encode_id }
return value_mapper
@web.expose_api
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/galaxy/webapps/tool_shed/api/repository_revisions.py
--- a/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
+++ b/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
@@ -68,7 +68,8 @@
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id,
- 'repository_id' : trans.security.encode_id }
+ 'repository_id' : trans.security.encode_id,
+ 'user_id' : trans.security.encode_id }
return value_mapper
@web.expose_api_anonymous
@@ -159,15 +160,33 @@
repository_dependency_repository_metadata = \
suc.get_repository_metadata_by_changeset_revision( trans, repository_dependency_id, changeset_revision )
if repository_dependency_repository_metadata is None:
- log.debug( 'Cannot locate repository_metadata with id %s for repository dependency %s owned by %s.' % \
- ( str( repository_dependency_id ), str( name ), str( owner ) ) )
- continue
+ # The changeset_revision column in the repository_metadata table has been updated with a new
+ # value value, so find the changeset_revision to which we need to update.
+ repo_dir = repository_dependency.repo_path( trans.app )
+ repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository_dependency,
+ repo,
+ changeset_revision )
+ repository_dependency_repository_metadata = \
+ suc.get_repository_metadata_by_changeset_revision( trans,
+ repository_dependency_id,
+ new_changeset_revision )
+ if repository_dependency_repository_metadata is None:
+ decoded_repository_dependency_id = trans.security.decode_id( repository_dependency_id )
+ debug_msg = 'Cannot locate repository_metadata with id %d for repository dependency %s owned by %s ' % \
+ ( decoded_repository_dependency_id, str( name ), str( owner ) )
+ debug_msg += 'using either of these changeset_revisions: %s, %s.' % \
+ ( str( changeset_revision ), str( new_changeset_revision ) )
+ log.debug( debug_msg )
+ continue
+ else:
+ changeset_revision = new_changeset_revision
repository_dependency_repository_metadata_id = trans.security.encode_id( repository_dependency_repository_metadata.id )
repository_dependency_dict = repository_dependency.to_dict( view='element',
value_mapper=self.__get_value_mapper( trans ) )
# We have to add the changeset_revision of of the repository dependency.
repository_dependency_dict[ 'changeset_revision' ] = changeset_revision
- repository_dependency_dict[ 'url' ] = web.url_for( controller='repositories',
+ repository_dependency_dict[ 'url' ] = web.url_for( controller='repository_revisions',
action='show',
id=repository_dependency_repository_metadata_id )
repository_dependencies_dicts.append( repository_dependency_dict )
diff -r b76dd608c500d8421d0ec51f6b638b7324ecead6 -r dec86d2bd3b10c16c91ec2847840c62b5e2bfe59 lib/tool_shed/util/shed_util_common.py
--- a/lib/tool_shed/util/shed_util_common.py
+++ b/lib/tool_shed/util/shed_util_common.py
@@ -724,8 +724,8 @@
def get_next_downloadable_changeset_revision( repository, repo, after_changeset_revision ):
"""
- Return the installable changeset_revision in the repository changelog after the changeset to which after_changeset_revision refers. If there
- isn't one, return None.
+ Return the installable changeset_revision in the repository changelog after the changeset to which
+ after_changeset_revision refers. If there isn't one, return None.
"""
changeset_revisions = get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True )
if len( changeset_revisions ) == 1:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: greg: Fixes in the tool shed api for mapping the repository user_id and for handling repository_dependency changeset_revision values that have been updated.
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/11bdc0f5c964/
Changeset: 11bdc0f5c964
User: greg
Date: 2014-01-16 20:07:28
Summary: Fixes in the tool shed api for mapping the repository user_id and for handling repository_dependency changeset_revision values that have been updated.
Affected #: 3 files
diff -r 1ffcb550e2f9464bf71a5f5154dff71ba0dd6379 -r 11bdc0f5c964a18e5a810abc283f7f1ec5e9f5ff lib/galaxy/webapps/tool_shed/api/repositories.py
--- a/lib/galaxy/webapps/tool_shed/api/repositories.py
+++ b/lib/galaxy/webapps/tool_shed/api/repositories.py
@@ -129,7 +129,7 @@
repository_metadata = suc.get_repository_metadata_by_changeset_revision( trans,
encoded_repository_id,
changeset_revision )
- if not repository_metadata:
+ if repository_metadata is None:
# The changeset_revision column in the repository_metadata table has been updated with a new
# value value, so find the changeset_revision to which we need to update.
repo_dir = repository.repo_path( trans.app )
@@ -139,7 +139,7 @@
encoded_repository_id,
new_changeset_revision )
changeset_revision = new_changeset_revision
- if repository_metadata:
+ if repository_metadata is not None:
encoded_repository_metadata_id = trans.security.encode_id( repository_metadata.id )
repository_metadata_dict = repository_metadata.to_dict( view='collection',
value_mapper=self.__get_value_mapper( trans ) )
@@ -168,7 +168,8 @@
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id,
- 'repository_id' : trans.security.encode_id }
+ 'repository_id' : trans.security.encode_id,
+ 'user_id' : trans.security.encode_id }
return value_mapper
@web.expose_api
diff -r 1ffcb550e2f9464bf71a5f5154dff71ba0dd6379 -r 11bdc0f5c964a18e5a810abc283f7f1ec5e9f5ff lib/galaxy/webapps/tool_shed/api/repository_revisions.py
--- a/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
+++ b/lib/galaxy/webapps/tool_shed/api/repository_revisions.py
@@ -68,7 +68,8 @@
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id,
- 'repository_id' : trans.security.encode_id }
+ 'repository_id' : trans.security.encode_id,
+ 'user_id' : trans.security.encode_id }
return value_mapper
@web.expose_api_anonymous
@@ -159,15 +160,33 @@
repository_dependency_repository_metadata = \
suc.get_repository_metadata_by_changeset_revision( trans, repository_dependency_id, changeset_revision )
if repository_dependency_repository_metadata is None:
- log.debug( 'Cannot locate repository_metadata with id %s for repository dependency %s owned by %s.' % \
- ( str( repository_dependency_id ), str( name ), str( owner ) ) )
- continue
+ # The changeset_revision column in the repository_metadata table has been updated with a new
+ # value value, so find the changeset_revision to which we need to update.
+ repo_dir = repository_dependency.repo_path( trans.app )
+ repo = hg.repository( suc.get_configured_ui(), repo_dir )
+ new_changeset_revision = suc.get_next_downloadable_changeset_revision( repository_dependency,
+ repo,
+ changeset_revision )
+ repository_dependency_repository_metadata = \
+ suc.get_repository_metadata_by_changeset_revision( trans,
+ repository_dependency_id,
+ new_changeset_revision )
+ if repository_dependency_repository_metadata is None:
+ decoded_repository_dependency_id = trans.security.decode_id( repository_dependency_id )
+ debug_msg = 'Cannot locate repository_metadata with id %d for repository dependency %s owned by %s ' % \
+ ( decoded_repository_dependency_id, str( name ), str( owner ) )
+ debug_msg += 'using either of these changeset_revisions: %s, %s.' % \
+ ( str( changeset_revision ), str( new_changeset_revision ) )
+ log.debug( debug_msg )
+ continue
+ else:
+ changeset_revision = new_changeset_revision
repository_dependency_repository_metadata_id = trans.security.encode_id( repository_dependency_repository_metadata.id )
repository_dependency_dict = repository_dependency.to_dict( view='element',
value_mapper=self.__get_value_mapper( trans ) )
# We have to add the changeset_revision of of the repository dependency.
repository_dependency_dict[ 'changeset_revision' ] = changeset_revision
- repository_dependency_dict[ 'url' ] = web.url_for( controller='repositories',
+ repository_dependency_dict[ 'url' ] = web.url_for( controller='repository_revisions',
action='show',
id=repository_dependency_repository_metadata_id )
repository_dependencies_dicts.append( repository_dependency_dict )
diff -r 1ffcb550e2f9464bf71a5f5154dff71ba0dd6379 -r 11bdc0f5c964a18e5a810abc283f7f1ec5e9f5ff lib/tool_shed/util/shed_util_common.py
--- a/lib/tool_shed/util/shed_util_common.py
+++ b/lib/tool_shed/util/shed_util_common.py
@@ -724,8 +724,8 @@
def get_next_downloadable_changeset_revision( repository, repo, after_changeset_revision ):
"""
- Return the installable changeset_revision in the repository changelog after the changeset to which after_changeset_revision refers. If there
- isn't one, return None.
+ Return the installable changeset_revision in the repository changelog after the changeset to which
+ after_changeset_revision refers. If there isn't one, return None.
"""
changeset_revisions = get_ordered_metadata_changeset_revisions( repository, repo, downloadable=True )
if len( changeset_revisions ) == 1:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: jmchilton: Fix database engine options when verifying tools using separate install database.
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/1ffcb550e2f9/
Changeset: 1ffcb550e2f9
User: jmchilton
Date: 2014-01-16 20:00:30
Summary: Fix database engine options when verifying tools using separate install database.
Bug report and fix thanks to Jim Johnson.
Affected #: 1 file
diff -r dd0bf9c3d0e42246964c8d65785ece1feec6b98e -r 1ffcb550e2f9464bf71a5f5154dff71ba0dd6379 lib/galaxy/config.py
--- a/lib/galaxy/config.py
+++ b/lib/galaxy/config.py
@@ -602,7 +602,11 @@
if check_migrate_tools:
# Alert the Galaxy admin to tools that have been moved from the distribution to the tool shed.
from tool_shed.galaxy_install.migrate.check import verify_tools
- verify_tools( self, install_db_url, config_file, self.config.database_engine_options )
+ if combined_install_database:
+ install_database_options = self.config.database_engine_options
+ else:
+ install_database_options = self.config.install_database_engine_options
+ verify_tools( self, install_db_url, config_file, install_database_options )
from galaxy.model import mapping
self.model = mapping.init( self.config.file_path,
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/dd0bf9c3d0e4/
Changeset: dd0bf9c3d0e4
User: martenson
Date: 2014-01-16 19:35:51
Summary: remove doubled import
Affected #: 1 file
diff -r 3149e4f0836584708c417c42e36250709026d18c -r dd0bf9c3d0e42246964c8d65785ece1feec6b98e lib/galaxy/webapps/galaxy/api/lda_datasets.py
--- a/lib/galaxy/webapps/galaxy/api/lda_datasets.py
+++ b/lib/galaxy/webapps/galaxy/api/lda_datasets.py
@@ -2,7 +2,6 @@
API operations on the datasets from library.
"""
import glob
-import logging
import operator
import os
import os.path
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: removed obvious bugs in api_key retrieval through API using basic authentication
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/3149e4f08365/
Changeset: 3149e4f08365
User: martenson
Date: 2014-01-16 19:30:53
Summary: removed obvious bugs in api_key retrieval through API using basic authentication
Affected #: 1 file
diff -r a24014287a29cddcd4ef392a4bde59a833c3ecab -r 3149e4f0836584708c417c42e36250709026d18c lib/galaxy/webapps/galaxy/api/authenticate.py
--- a/lib/galaxy/webapps/galaxy/api/authenticate.py
+++ b/lib/galaxy/webapps/galaxy/api/authenticate.py
@@ -10,7 +10,6 @@
from galaxy.exceptions import ObjectNotFound
from paste.httpexceptions import HTTPBadRequest
-
import logging
log = logging.getLogger( __name__ )
@@ -23,7 +22,7 @@
* GET /api/authenticate/baseauth
returns an API key for authenticated user based on BaseAuth headers
"""
- email, password = _decode_baseauth( trans.environ.get( 'HTTP_AUTHORIZATION' ) )
+ email, password = self._decode_baseauth( trans.environ.get( 'HTTP_AUTHORIZATION' ) )
user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email == email ).all()
@@ -41,38 +40,38 @@
trans.response.status = 500
return "invalid password"
- return dict('api_key', api_key_row.key)
+ return dict( api_key= api_key_row.key )
-def _decode_baseauth( encoded_str ):
- """Decode an encrypted HTTP basic authentication string. Returns a tuple of
- the form (email, password), and raises a DecodeError exception if
- nothing could be decoded.
- """
- split = encoded_str.strip().split(' ')
+ def _decode_baseauth( self, encoded_str ):
+ """Decode an encrypted HTTP basic authentication string. Returns a tuple of
+ the form (email, password), and raises a HTTPBadRequest exception if
+ nothing could be decoded.
+ """
+ split = encoded_str.strip().split(' ')
- # If split is only one element, try to decode the email and password
- # directly.
- if len(split) == 1:
- try:
- email, password = b64decode(split[0]).split(':')
- except:
- raise HTTPBadRequest
+ # If split is only one element, try to decode the email and password
+ # directly.
+ if len(split) == 1:
+ try:
+ email, password = b64decode(split[0]).split(':')
+ except:
+ raise HTTPBadRequest
- # If there are only two elements, check the first and ensure it says
- # 'basic' so that we know we're about to decode the right thing. If not,
- # bail out.
- elif len(split) == 2:
- if split[0].strip().lower() == 'basic':
- try:
- email, password = b64decode(split[1]).split(':')
- except:
- raise DecodeError
+ # If there are only two elements, check the first and ensure it says
+ # 'basic' so that we know we're about to decode the right thing. If not,
+ # bail out.
+ elif len(split) == 2:
+ if split[0].strip().lower() == 'basic':
+ try:
+ email, password = b64decode(split[1]).split(':')
+ except:
+ raise HTTPBadRequest
+ else:
+ raise HTTPBadRequest
+
+ # If there are more than 2 elements, something crazy must be happening.
+ # Bail.
else:
raise HTTPBadRequest
- # If there are more than 2 elements, something crazy must be happening.
- # Bail.
- else:
- raise HTTPBadRequest
-
- return unquote(email), unquote(password)
+ return unquote(email), unquote(password)
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: api_key retrieval through API using basic authentication
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a24014287a29/
Changeset: a24014287a29
User: martenson
Date: 2014-01-16 19:20:10
Summary: api_key retrieval through API using basic authentication
Affected #: 3 files
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r a24014287a29cddcd4ef392a4bde59a833c3ecab lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -734,8 +734,7 @@
self.tags = []
def _next_hid( self ):
- # TODO: override this with something in the database that ensures
- # better integrity
+ # this is overriden in mapping.py db_next_hid() method
if len( self.datasets ) == 0:
return 1
else:
@@ -3446,4 +3445,7 @@
self.context = context
class APIKeys( object ):
- pass
+ def __init__( self, id=None, user_id=None, key=None):
+ self.id = id
+ self.user_id = user_id
+ self.key = key
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r a24014287a29cddcd4ef392a4bde59a833c3ecab lib/galaxy/webapps/galaxy/api/authenticate.py
--- /dev/null
+++ b/lib/galaxy/webapps/galaxy/api/authenticate.py
@@ -0,0 +1,78 @@
+"""
+API key retrieval through BaseAuth
+"""
+
+from galaxy import util, web
+from pprint import pprint
+from galaxy.web.base.controller import BaseAPIController
+from base64 import b64decode, b64encode
+from urllib import quote, unquote
+from galaxy.exceptions import ObjectNotFound
+from paste.httpexceptions import HTTPBadRequest
+
+
+import logging
+log = logging.getLogger( __name__ )
+
+class AuthenticationController( BaseAPIController ):
+
+ @web.expose_api_anonymous
+ def get_api_key( self, trans, **kwd ):
+ """
+ def get_api_key( self, trans, **kwd )
+ * GET /api/authenticate/baseauth
+ returns an API key for authenticated user based on BaseAuth headers
+ """
+ email, password = _decode_baseauth( trans.environ.get( 'HTTP_AUTHORIZATION' ) )
+
+ user = trans.sa_session.query( trans.app.model.User ).filter( trans.app.model.User.table.c.email == email ).all()
+
+ if (len(user) is not 1):
+ # DB is inconsistent and we have more users with same email
+ raise ObjectNotFound
+ else:
+ user = user[0]
+ is_valid_user = user.check_password( password )
+
+ if (is_valid_user):
+ user_id = user.id
+ api_key_row = trans.sa_session.query( trans.app.model.APIKeys ).filter( trans.app.model.APIKeys.table.c.user_id == user_id ).first()
+ else:
+ trans.response.status = 500
+ return "invalid password"
+
+ return dict('api_key', api_key_row.key)
+
+def _decode_baseauth( encoded_str ):
+ """Decode an encrypted HTTP basic authentication string. Returns a tuple of
+ the form (email, password), and raises a DecodeError exception if
+ nothing could be decoded.
+ """
+ split = encoded_str.strip().split(' ')
+
+ # If split is only one element, try to decode the email and password
+ # directly.
+ if len(split) == 1:
+ try:
+ email, password = b64decode(split[0]).split(':')
+ except:
+ raise HTTPBadRequest
+
+ # If there are only two elements, check the first and ensure it says
+ # 'basic' so that we know we're about to decode the right thing. If not,
+ # bail out.
+ elif len(split) == 2:
+ if split[0].strip().lower() == 'basic':
+ try:
+ email, password = b64decode(split[1]).split(':')
+ except:
+ raise DecodeError
+ else:
+ raise HTTPBadRequest
+
+ # If there are more than 2 elements, something crazy must be happening.
+ # Bail.
+ else:
+ raise HTTPBadRequest
+
+ return unquote(email), unquote(password)
diff -r ee176b881f3784ab658254ff4d471bcd113f05ce -r a24014287a29cddcd4ef392a4bde59a833c3ecab lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -169,6 +169,16 @@
webapp.mapper.connect( 'workflow_dict', '/api/workflows/download/{workflow_id}', controller='workflows', action='workflow_dict', conditions=dict( method=['GET'] ) )
webapp.mapper.connect( 'import_shared_workflow', '/api/workflows/import', controller='workflows', action='import_shared_worflow', conditions=dict( method=['POST'] ) )
+ # ============================
+ # ===== AUTHENTICATE API =====
+ # ============================
+
+ webapp.mapper.connect( 'api_key_retrieval',
+ '/api/authenticate/baseauth/',
+ controller='authenticate',
+ action='get_api_key',
+ conditions=dict( method=[ "GET" ] ) )
+
# =======================
# ===== LIBRARY API =====
# =======================
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Charts: Update view organization
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ee176b881f37/
Changeset: ee176b881f37
User: guerler
Date: 2014-01-16 18:24:47
Summary: Charts: Update view organization
Affected #: 14 files
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -1,9 +1,9 @@
// dependencies
define(['library/portlet', 'library/ui', 'library/utils',
- 'main', 'viewport', 'create', 'config',
+ 'views/charts', 'views/viewport', 'views/chart', 'views/group',
'models/datasets', 'models/chart', 'models/charts', 'models/types'],
function( Portlet, Ui, Utils,
- Main, Viewport, Create, Config,
+ ChartsView, ViewportView, ChartView, GroupView,
Datasets, Chart, Charts, Types
) {
@@ -19,32 +19,32 @@
// link galaxy
this.modal = parent.Galaxy.modal;
- // create chart objects
+ // create chart models
this.types = new Types();
this.chart = new Chart();
- this.charts = new Charts(this);
+ this.charts = new Charts();
// create dataset handler
this.datasets = new Datasets(this);
// create views
- this.main = new Main(this);
- this.viewport = new Viewport(this);
- this.config = new Config(this);
- this.create = new Create(this);
+ this.charts_view = new ChartsView(this);
+ this.group_view = new GroupView(this);
+ this.chart_view = new ChartView(this);
+ this.viewport_view = new ViewportView(this);
// portlet
this.portlet = new Portlet({icon : 'fa-bar-chart-o', label : 'Charts'});
- this.portlet.append(this.main.$el);
- this.portlet.append(this.config.$el);
- this.portlet.append(this.create.$el);
+ this.portlet.append(this.charts_view.$el);
+ this.portlet.append(this.group_view.$el);
+ this.portlet.append(this.chart_view.$el);
// append main
- this.main.append(this.viewport.$el);
+ this.charts_view.append(this.viewport_view.$el);
// create
- this.config.$el.hide();
- this.main.$el.hide();
+ this.group_view.$el.hide();
+ this.charts_view.$el.hide();
// set elements
this.setElement(this.portlet.$el);
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/config.js
--- a/config/plugins/visualizations/charts/static/config.js
+++ /dev/null
@@ -1,219 +0,0 @@
-// dependencies
-define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/group'],
- function(Portlet, Table, Ui, Utils, Group) {
-
-// chart config
-return Backbone.View.extend(
-{
- // model
- group: new Group(),
-
- // columns
- columns: [],
-
- // initialize
- initialize: function(app, options) {
- // link app
- this.app = app;
-
- // get current chart object
- this.chart = this.app.chart;
-
- // ui elements
- this.message = new Ui.Message();
- this.label = new Ui.Input({placeholder: 'Group label'});
- this.table = new Table({content: 'No data column.'});
-
- // add table to portlet
- var self = this;
- this.portlet = new Portlet({
- icon : 'fa-edit',
- label : 'Define group properties:',
- operations : {
- 'save' : new Ui.ButtonIcon({
- icon : 'fa-save',
- tooltip : 'Save',
- onclick : function() {
- // save/add group
- self._saveGroup();
- }
- }),
- 'back' : new Ui.ButtonIcon({
- icon : 'fa-caret-left',
- tooltip : 'Return',
- onclick : function() {
- self.$el.hide();
- self.app.create.$el.show();
- }
- })
- }
- });
- this.portlet.append(this.message.$el);
- this.portlet.append(this.label.$el);
- this.portlet.append(this.table.$el);
-
- // add element
- this.setElement(this.portlet.$el);
-
- // change
- var self = this;
- this.chart.on('change:dataset_id', function() {
- self._refreshDataset();
- });
- this.chart.on('change:type', function() {
- self._refreshType();
- });
- this.group.on('change:label', function() {
- self._refreshLabel();
- });
- this.group.on('change', function() {
- self._refreshGroup();
- });
- },
-
- // show
- show: function() {
- this.$el.show();
- },
-
- // reset
- reset: function() {
- this.group.reset();
- this.group.set('id', Utils.uuid());
- this.group.set('label', 'Group label');
- },
-
- // update dataset
- _refreshDataset: function() {
- // identify datasets
- var dataset_id = this.chart.get('dataset_id');
-
- // check if dataset is available
- if (!dataset_id) {
- return;
- }
-
- // get dataset
- var dataset = this.app.datasets.get({id : dataset_id});
-
- // check
- if (!dataset) {
- this.app.log('Config::render()', 'Failed to retrieve dataset.');
- return;
- }
-
- // configure columns
- this.columns = [];
- var meta = dataset.metadata_column_types;
- for (var key in meta){
- this.columns.push({
- 'label' : key + ' [' + meta[key] + ']',
- 'value' : key
- });
- }
-
- // update select fields
- for (var key in this.list) {
- this.list[key].update(this.columns);
- }
- },
-
- // update
- _refreshType: function() {
- // configure chart type
- var self = this;
- var chart_type = this.chart.get('type');
- if (chart_type) {
- var chart_settings = this.app.types.get(chart_type);
-
- // table
- this.table.removeAll();
- this.list = {};
- for (var id in chart_settings.data) {
- // create select field
- var data_def = chart_settings.data[id];
- var select = new Ui.Select({
- id : 'select_' + id,
- gid : id,
- data : this.columns,
- onchange : function(value) {
- self.group.set(this.gid, value);
- }
- });
-
- // add row to table
- this.table.add(data_def.title);
- this.table.add(select.$el);
- this.table.append(id);
-
- // add select field to list
- this.list[id] = select;
- }
- }
- },
-
- // update
- _refreshGroup: function() {
- // update select fields
- for (var id in this.list) {
- var col = this.group.get(id);
- if (col === undefined) {
- col = 0;
- }
- this.list[id].value(col);
- }
- },
-
- // update label
- _refreshLabel: function() {
- var label_text = this.group.get('label');
- if (label_text === undefined) {
- label_text = '';
- }
- this.label.value(label_text);
- },
-
- // create group
- _saveGroup: function() {
- // get current chart
- var chart = this.chart;
-
- // update group object
- var group = this.group;
- for (var key in this.list) {
- group.set(key, this.list[key].value());
- }
-
- // add label
- group.set({
- dataset_id : this.chart.get('dataset_id'),
- label : this.label.value(),
- date : Utils.time()
- });
-
- // validate
- if (!group.get('label')) {
- this.message.update({message : 'Please enter a label for your group.'});
- return;
- }
-
- // get groups of current chart
- var groups = this.chart.groups;
-
- // create/update group
- var group_update = groups.get(group.id);
- if (group_update) {
- group_update.set(group.attributes);
- } else {
- groups.add(group.clone());
- }
-
- // hide
- this.$el.hide();
-
- // update main
- this.app.create.$el.show();
- }
-});
-
-});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/create.js
--- a/config/plugins/visualizations/charts/static/create.js
+++ /dev/null
@@ -1,207 +0,0 @@
-// dependencies
-define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/chart', 'groups'],
- function(Portlet, Table, Ui, Utils, Chart, Groups) {
-
-// widget
-return Backbone.View.extend(
-{
- // defaults options
- optionsDefault: {
- header : true,
- content : 'No content available.'
- },
-
- // current chart
- chart : null,
-
- // initialize
- initialize: function(app, options)
- {
- // link application
- this.app = app;
-
- // get current chart object
- this.chart = this.app.chart;
-
- // configure options
- this.options = Utils.merge(options, this.optionsDefault);
-
- // main elements
- this.message = new Ui.Message();
- this.title = new Ui.Input({placeholder: 'Chart title'});
- this.dataset = new Ui.Input({value : app.options.dataset.id, disabled: true, visible: false});
-
- // configure dataset
- this.groups = new Groups(this.app);
-
- // table
- var self = this;
- this.table = new Table({
- header : false,
- onconfirm : function(type) {
- if (self.chart.groups.length > 0) {
- // show modal
- self.app.modal.show({
- title : 'Switching the chart type?',
- body : 'You configured data sources. If you switch chart types your configurations will be removed.',
- buttons : {
- 'Cancel' : function() {
- // hide modal
- self.app.modal.hide();
- },
- 'Continue' : function() {
- // hide modal
- self.app.modal.hide();
-
- // confirm
- self.table.confirm(type);
- }
- }
- });
- } else {
- // confirm
- self.table.confirm(type);
- }
- },
- onchange : function(type) {
- // update chart type
- self.chart.set({type: type});
-
- // reset groups
- self.chart.groups.reset();
- },
- content: 'No chart types available'
- });
-
- // add types
- var types_n = 0;
- var types = app.types.attributes;
- for (var id in types){
- var chart_type = types[id];
- this.table.add (++types_n + '.');
- this.table.add (chart_type.title);
- this.table.append(id);
- }
-
- // add table to portlet
- var self = this;
- this.portlet = new Portlet({
- icon : 'fa-edit',
- label : 'Create a new chart:',
- operations : {
- 'save' : new Ui.ButtonIcon({
- icon : 'fa-save',
- tooltip : 'Save Chart',
- onclick : function() {
- self._saveChart();
- }
- }),
- 'back' : new Ui.ButtonIcon({
- icon : 'fa-caret-left',
- tooltip : 'Return',
- onclick : function() {
- self.$el.hide();
- self.app.main.$el.show();
- }
- })
- }
- });
- this.portlet.append(this.message.$el);
- this.portlet.append(this.dataset.$el);
- this.portlet.append((new Ui.Label({ label : 'Provide a chart title:'})).$el);
- this.portlet.append(this.title.$el);
- this.portlet.append((new Ui.Label({ label : 'Select a chart type:'})).$el);
- this.portlet.append(this.table.$el);
- this.portlet.append(this.groups.$el);
-
- // elements
- this.setElement(this.portlet.$el);
-
- // hide back button on startup
- this.portlet.hideOperation('back');
-
- // model events
- var self = this;
- this.chart.on('change:title', function(chart) {
- self.title.value(chart.get('title'));
- });
- this.chart.on('change:type', function(chart) {
- self.table.value(chart.get('type'));
- });
-
- // collection events
- this.app.charts.on('add', function(chart) {
- self.portlet.showOperation('back');
- });
- this.app.charts.on('remove', function(chart) {
- if (self.app.charts.length == 1) {
- self.portlet.hideOperation('back');
- }
- });
- this.app.charts.on('reset', function(chart) {
- self.portlet.hideOperation('back');
- });
-
- // reset
- this.reset();
- },
-
- // reset
- reset: function() {
- this.chart.reset();
- this.chart.set('id', Utils.uuid());
- this.chart.set('dataset_id', this.app.options.dataset.id);
- this.chart.set('type', 'bardiagram');
- this.chart.set('title', 'Chart title');
- },
-
- // set chart
- setChart: function(new_chart) {
- this.chart.copy(new_chart);
- },
-
- // create chart
- _saveChart: function() {
- // update chart data
- this.chart.set({
- type : this.table.value(),
- title : this.title.value(),
- dataset_id : this.dataset.value(),
- date : Utils.time()
- });
-
- // validate
- if (!this.chart.get('title')) {
- this.message.update({message : 'Please enter a title for your chart.'});
- return;
- }
-
- if (!this.chart.get('type')) {
- this.message.update({message : 'Please select a chart type.'});
- return;
- }
-
- if (this.chart.groups.length == 0) {
- this.message.update({message : 'Please configure at least one data source.'});
- return;
- }
-
- // create/get chart
- var current = this.app.charts.get(this.chart.id);
- if (!current) {
- current = this.chart.clone();
- this.app.charts.add(current);
- }
-
- // update chart model
- current.copy(this.chart);
-
- // hide
- this.$el.hide();
-
- // update main
- this.app.main.$el.show();
- }
-});
-
-});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/groups.js
--- a/config/plugins/visualizations/charts/static/groups.js
+++ /dev/null
@@ -1,154 +0,0 @@
-// dependencies
-define(['library/portlet', 'library/table', 'library/ui', 'library/utils'], function(Portlet, Table, Ui, Utils) {
-
-// chart config
-return Backbone.View.extend(
-{
- // initialize
- initialize: function(app, options) {
- // link app
- this.app = app;
-
- // get current chart object
- this.chart = this.app.chart;
-
- // table
- this.table = new Table({
- content : 'Add data columns to this table.',
- ondblclick : function(group_id) {
- // get group
- var group = self.app.chart.groups.get(group_id);
-
- // show edit
- self.app.create.$el.hide();
- self.app.config.show();
- self.app.config.group.set(group.attributes);
- }
- });
-
- // add table to portlet
- var self = this;
- this.portlet = new Portlet({
- icon : '',
- label : 'Select data columns:',
- height : 100,
- operations : {
- 'new' : new Ui.ButtonIcon({
- icon : 'fa-plus',
- tooltip: 'Create',
- onclick: function() {
- self.app.create.$el.hide();
- self.app.config.show();
- self.app.config.reset();
- }
- }),
- 'edit' : new Ui.ButtonIcon({
- icon : 'fa-pencil',
- tooltip: 'Edit',
- onclick: function() {
- // check if element has been selected
- var group_id = self.table.value();
- if (!group_id) {
- return;
- }
-
- // get group
- var group = self.app.chart.groups.get(group_id);
-
- // show edit
- self.app.create.$el.hide();
- self.app.config.show();
- self.app.config.group.set(group.attributes);
- }
- }),
- 'delete' : new Ui.ButtonIcon({
- icon : 'fa-minus',
- tooltip: 'Delete',
- onclick: function() {
- // check if element has been selected
- var id = self.table.value();
- if (!id) {
- return;
- }
- // remove group from chart
- self.chart.groups.remove(id);
- }
- })
- }
- });
- this.portlet.append(this.table.$el);
-
- // add element
- this.setElement(this.portlet.$el);
-
- // change
- var self = this;
- this.chart.on('change', function() {
- self._refresh();
- });
- this.chart.on('reset', function() {
- self._removeGroupAll();
- });
- this.chart.on('change:type', function() {
- self.app.config.trigger('change');
- });
- this.chart.groups.on('add', function(group) {
- self._addGroup(group);
- });
- this.chart.groups.on('remove', function(group) {
- self._removeGroup(group);
- });
- this.chart.groups.on('reset', function(group) {
- self._removeGroupAll();
- });
- this.chart.groups.on('change', function(group) {
- self._removeGroup(group);
- self._addGroup(group);
- });
- },
-
- // refresh
- _refresh: function() {
- this._removeGroupAll();
- var self = this;
- var groups = this.chart.groups;
- if (groups) {
- groups.each(function(group) { self._addGroup(group); });
- }
- },
-
- // add
- _addGroup: function(group) {
- // make custom info string
- var info = '[';
- var chart_type = this.chart.get('type');
- if (chart_type) {
- var chart_settings = this.app.types.get(chart_type);
- for (var key in chart_settings.data) {
- info += key + '=' + group.get(key) + ', '
- }
- }
- info = info.substring(0, info.length - 2) + ']';
-
- // add to table
- this.table.add(group.get('label'));
- this.table.add(info);
- this.table.add('Last changed: ' + group.get('date'));
- this.table.prepend(group.id);
- this.table.value(group.id);
- },
-
- // remove
- _removeGroup: function(group) {
- // remove from to table
- this.table.remove(group.id);
- },
-
- // data config reset
- _removeGroupAll: function() {
- // reset options table
- this.table.removeAll();
- }
-});
-
-});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/library/ui.js
--- a/config/plugins/visualizations/charts/static/library/ui.js
+++ b/config/plugins/visualizations/charts/static/library/ui.js
@@ -48,14 +48,14 @@
this.options = Utils.merge(options, this.optionsDefault);
// create new element
- this.setElement(this.template(this.options));
+ this.setElement(this._template(this.options));
// add event
$(this.el).on('click', options.onclick);
},
// element
- template: function(options) {
+ _template: function(options) {
var str = '<button id="' + options.id + '" type="' + options.type + '" style="margin-right: 5px; float: ' + options.float + ';" type="button" class="btn ' + options.cls + '">';
if (options.icon) {
str += '<i class="icon fa ' + options.icon + '"></i> ' ;
@@ -80,14 +80,14 @@
this.options = Utils.merge(options, this.optionsDefault);
// create new element
- this.setElement(this.template(this.options));
+ this.setElement(this._template(this.options));
// add event
$(this.el).on('click', options.onclick);
},
// element
- template: function(options) {
+ _template: function(options) {
return '<div><a href="javascript:void(0)">' + options.label + '</a></div>';
}
});
@@ -218,7 +218,7 @@
var ButtonMenu = Backbone.View.extend(
{
// main options
- options:
+ optionsDefault:
{
id : '',
title : '',
@@ -237,9 +237,8 @@
// initialize
initialize: function (options)
{
- // read in defaults
- if (options)
- this.options = _.defaults(options, this.options);
+ // get options
+ this.options = Utils.merge(options, this.optionsDefault);
// add template for tab
this.setElement($(this._template(this.options)));
@@ -290,9 +289,8 @@
icon : null
}
- // read in defaults
- if (options)
- menuOptions = _.defaults(options, menuOptions);
+ // get options
+ menuOptions = Utils.merge(options, menuOptions);
// check if submenu element is available
if (!this.$menu)
@@ -388,10 +386,7 @@
// initialize
initialize : function(options) {
// get options
- if (options)
- this.options = _.defaults(options, this.optionsDefault);
- else
- this.options = this.optionsDefault;
+ this.options = Utils.merge(options, this.optionsDefault);
// create new element
this.setElement(this.template(this.options));
@@ -430,11 +425,8 @@
// initialize
initialize : function(options) {
- // get options
- if (options)
- this.options = _.defaults(options, this.optionsDefault);
- else
- this.options = this.optionsDefault;
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
// create new element
this.setElement(this.template(this.options));
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/library/ui.select.js
--- a/config/plugins/visualizations/charts/static/library/ui.select.js
+++ b/config/plugins/visualizations/charts/static/library/ui.select.js
@@ -1,14 +1,14 @@
// dependencies
define(['library/utils'], function(Utils) {
-
// plugin
return Backbone.View.extend(
{
// options
optionsDefault: {
- id : '',
- cls : ''
+ id : '',
+ cls : '',
+ empty : 'No data available'
},
// initialize
@@ -17,21 +17,41 @@
this.options = Utils.merge(options, this.optionsDefault);
// create new element
- this.setElement(this.template(this.options));
+ this.setElement(this._template(this.options));
// add change event
var self = this;
if (this.options.onchange) {
- this.$el.on('change', function() { self.options.onchange(self.value()) });
+ this.$el.on('change', function() { self.options.onchange(self.value()); });
}
+
+ // refresh
+ this._refresh();
},
// value
- value : function (new_val) {
- if (new_val !== undefined) {
- this.$el.val(new_val);
+ value : function (new_value) {
+ // get current id/value
+ var before = this.$el.val();
+
+ // check if new_value is defined
+ if (new_value !== undefined) {
+ this.$el.val(new_value);
}
- return this.$el.val();
+
+ // get current id/value
+ var after = this.$el.val();
+ if(after === undefined) {
+ return null;
+ } else {
+ // fire onchange
+ if ((after != before && this.options.onchange) || this.$el.find('option').length == 1) {
+ this.options.onchange(after);
+ }
+
+ // return current value
+ return after;
+ }
},
// label
@@ -43,6 +63,35 @@
disabled: function() {
return this.$el.is(':disabled');
},
+
+ // enable
+ enable: function() {
+ this.$el.prop('disabled', false);
+ },
+
+ // disable
+ disable: function() {
+ this.$el.prop('disabled', true);
+ },
+
+ // add
+ add: function(options) {
+ // add options
+ $(this.el).append(this._templateOption(options));
+
+ // refresh
+ this._refresh();
+ },
+
+ // remove
+ remove: function(value) {
+ // remove option
+ $(this.el).find('option[value=' + value + ']').remove();
+ $(this.el).trigger('change');
+
+ // refresh
+ this._refresh();
+ },
// render
update: function(options) {
@@ -54,47 +103,46 @@
// add new options
for (var key in options.data) {
- $(this.el).append(this.templateOption(options.data[key]));
+ $(this.el).append(this._templateOption(options.data[key]));
}
- // check if selected value exists
- var exists = 0 != $(this.el).find('option[value=' + selected + ']').length;
+ // add selected value
+ if (this._exists(selected))
+ $(this.el).val(selected);
- // add selected value
- if (exists)
- $(this.el).val(selected);
+ // refresh
+ this._refresh();
},
- // update from url
- updateUrl : function(options, callback) {
- // get json
- var self = this;
- Utils.get(options.url, function(json) {
- // write data into array
- var data = [];
- for (key in json) {
- data.push({label: json[key].name, value: json[key].id});
- }
-
- // check if disabled. do not update disabled select elements.
- if (!self.disabled()) {
- self.update({data: data});
- }
-
- // callback
- if (callback) {
- callback();
- }
- });
+ // refresh
+ _refresh: function() {
+ // remove placeholder
+ $(this.el).find('option[value=null]').remove();
+
+ // count remaining entries
+ var remaining = $(this.el).find('option').length;
+ if (remaining == 0) {
+ // append placeholder
+ $(this.el).append(this._templateOption({value : 'null', label : this.options.empty}));
+ this.disable();
+ } else {
+ this.enable();
+ }
+ },
+
+ // exists
+ _exists: function(value) {
+ // check if selected value exists
+ return 0 != $(this.el).find('option[value=' + value + ']').length;
},
// option
- templateOption: function(options) {
+ _templateOption: function(options) {
return '<option value="' + options.value + '">' + options.label + '</option>';
},
// element
- template: function(options) {
+ _template: function(options) {
var tmpl = '<select id="' + options.id + '" class="select ' + options.cls + ' ' + options.id + '">';
for (key in options.data) {
// options
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/library/utils.js
--- a/config/plugins/visualizations/charts/static/library/utils.js
+++ b/config/plugins/visualizations/charts/static/library/utils.js
@@ -6,21 +6,6 @@
request('GET', url, {}, success, error);
};
-// delete
-function del (url, success, error) {
- request('DELETE', url, {}, success, error);
-};
-
-// post
-function post (url, data, success, error) {
- request('POST', url, data, success, error);
-};
-
-// put
-function put (url, data, success, error) {
- request('PUT', url, data, success, error);
-};
-
// generic function to send json to url
function request (method, url, data, success, error) {
@@ -134,11 +119,8 @@
return {
cssLoadFile : cssLoadFile,
cssGetAttribute : cssGetAttribute,
+ get : get,
merge : merge,
- get : get,
- post : post,
- del : del,
- put : put,
request: request,
uuid: uuid,
wrap : wrap,
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/main.js
--- a/config/plugins/visualizations/charts/static/main.js
+++ /dev/null
@@ -1,150 +0,0 @@
-// dependencies
-define(['library/portlet', 'library/table', 'library/ui', 'library/utils'], function(Portlet, Table, Ui, Utils) {
-
-// widget
-return Backbone.View.extend(
-{
- // initialize
- initialize: function(app, options)
- {
- // link app
- this.app = app;
-
- // table
- this.table = new Table({
- content : 'Add charts to this table.',
- ondblclick : function(chart_id) {
- // get chart
- var chart = self.app.charts.get(chart_id);
-
- // show edit
- self.$el.hide();
-
- // update model and show create
- self.app.create.setChart(chart);
- self.app.create.$el.show();
- },
- onchange : function(chart_id) {
- self.app.viewport.show(chart_id);
- }
- });
-
- // add table to portlet
- var self = this;
- this.portlet = new Portlet({
- icon : 'fa-list',
- label : 'List of created charts:',
- height : 100,
- operations : {
- 'new' : new Ui.ButtonIcon({
- icon : 'fa-plus',
- tooltip: 'Create',
- onclick: function() {
- self.$el.hide();
- self.app.create.reset();
- self.app.create.$el.show();
- }
- }),
- 'edit' : new Ui.ButtonIcon({
- icon : 'fa-pencil',
- tooltip: 'Edit',
- onclick: function() {
- // check if element has been selected
- var chart_id = self.table.value();
- if (!chart_id) {
- return;
- }
-
- // get chart
- var chart = self.app.charts.get(chart_id);
-
- // show edit
- self.$el.hide();
- self.app.create.$el.show();
- self.app.create.setChart(chart);
- }
- }),
- 'delete' : new Ui.ButtonIcon({
- icon : 'fa-minus',
- tooltip: 'Delete',
- onclick: function() {
-
- // check if element has been selected
- var chart_id = self.table.value();
- if (!chart_id) {
- return;
- }
-
- // title
- var chart = self.app.charts.get(chart_id);
-
- // show modal
- self.app.modal.show({
- title : 'Are you sure?',
- body : 'The selected chart "' + chart.get('title') + '" will be irreversibly deleted.',
- buttons : {
- 'Cancel' : function() {self.app.modal.hide();},
- 'Delete' : function() {
- // hide modal
- self.app.modal.hide();
-
- // remove chart
- self.app.charts.remove(chart_id);
- }
- }
- });
- }
- }),
- }
- });
- this.portlet.append(this.table.$el);
-
- // append to main
- this.$el.append(this.portlet.$el);
-
- // events
- var self = this;
- this.app.charts.on('add', function(chart) {
- // add
- self._addChart(chart);
- });
- this.app.charts.on('remove', function(chart) {
- // remove
- self._removeChart(chart);
- });
- this.app.charts.on('change', function(chart) {
- // replace
- self._removeChart(chart);
- self._addChart(chart);
- });
- },
-
- // append
- append : function($el) {
- this.$el.append(Utils.wrap(''));
- this.$el.append($el);
- },
-
- // add
- _addChart: function(chart) {
- // add title to table
- this.table.add(chart.get('title'));
-
- // get chart type
- var type = this.app.types.get(chart.get('type'));
- this.table.add(type.title);
-
- // add additional columns
- this.table.add('Last change: ' + chart.get('date'));
- this.table.prepend(chart.get('id'));
- this.table.value(chart.get('id'));
- },
-
- // remove
- _removeChart: function(chart) {
- // remove from to table
- this.table.remove(chart.id);
- }
-});
-
-});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/viewport.js
--- a/config/plugins/visualizations/charts/static/viewport.js
+++ /dev/null
@@ -1,202 +0,0 @@
-// dependencies
-define(['library/portlet', 'library/ui', 'library/utils'],
- function(Portlet, Ui, Utils) {
-
-// widget
-return Backbone.View.extend(
-{
- // list
- list: {},
-
- // options
- optionsDefault :
- {
- height : 300
- },
-
- // initialize
- initialize: function(app, options)
- {
- // link app
- this.app = app;
-
- // link options
- this.options = Utils.merge(options, this.optionsDefault);
-
- // add table to portlet
- this.portlet = new Portlet({
- height : this.options.height,
- overflow : 'hidden'
- });
-
- // set this element
- this.setElement(this.portlet.$el);
-
- // events
- var self = this;
-
- // add
- this.app.charts.on('add', function(chart) {
- self._addChart(chart);
- });
-
- // remove
- this.app.charts.on('remove', function(chart) {
- self._removeChart(chart.id);
- });
-
- // replace
- this.app.charts.on('change', function(chart) {
- self._removeChart(chart.id);
- self._addChart(chart);
- });
- },
-
- // show
- show: function(id) {
- // hide all
- this.$el.find('svg').hide();
-
- var item = this.list[id];
- if (item) {
- // show selected chart
- this.$el.find(item.svg_id).show();
-
- // this trigger d3 update events
- $(window).trigger('resize');
- }
- },
-
- // add
- _addChart: function(chart) {
- // make sure that svg does not exist already
- this._removeChart(chart.id);
-
- // create id
- var svg_id = '#svg_' + chart.id;
-
- // create element
- var chart_el = $(this._template({id: svg_id, height : this.options.height}));
-
- // add to portlet
- this.portlet.append(chart_el);
-
- // backup id
- this.list[chart.id] = {
- svg_id : svg_id
- }
-
- // identify chart type
- var chart_type = chart.get('type');
- var chart_settings = this.app.types.get(chart_type);
-
- // create chart view
- var self = this;
- require(['charts/' + chart_type], function(ChartView) {
- // create chart
- var view = new ChartView(self.app, {svg_id : svg_id, chart : chart});
-
- // reset chart data
- var chart_data = [];
-
- // request data
- var chart_index = 0;
- chart.groups.each(function(group) {
-
- // add group data
- chart_data.push({
- key : (chart_index + 1) + ':' + group.get('label'),
- values : []
- });
-
- // get data
- for (var key in chart_settings.data) {
- // configure request
- var data_options = {
- view : view,
- data : chart_data,
- index : chart_index,
- dataset_id : group.get('dataset_id'),
- column : group.get(key),
- column_key : key
- }
-
- // make request
- self._data(data_options);
- }
-
- // count
- chart_index++;
- });
-
- // add view
- self.list[chart.id].view = view;
- });
- },
-
- // data
- _data: function(options) {
- // gather objects
- var view = options.view;
- var data = options.data;
-
- // gather parameters
- var index = options.index;
- var column = options.column;
- var dataset_id = options.dataset_id;
- var column_key = options.column_key;
- var group_data = data[options.index];
-
- // send request
- self.app.datasets.get({id : dataset_id, column: column}, function(dataset) {
- // select column
- var values = dataset.values[column];
- var n_values = values.length;
-
- // read column values
- var column_values = [];
- for (var i = 0; i < n_values; i++) {
- var value = values[i];
- if(!isNaN(value)) {
- column_values.push(value);
- } else {
- column_values.push(0)
- }
- }
-
- // write column values
- for (var i = 0; i < n_values; i++) {
- // make sure dictionary exists
- if (group_data.values[i] === undefined) {
- group_data.values[i] = {
- x : i,
- y : 0
- }
- }
-
- // write data
- group_data.values[i][column_key] = column_values[i];
- }
-
- // refresh view
- view.refresh(data);
- });
-
- },
-
- // remove
- _removeChart: function(id) {
- var item = this.list[id];
- if (item) {
- d3.select(item.svg_id).remove();
- $(item.svg_id).remove();
- }
- },
-
- // template
- _template: function(options) {
- return '<svg id="' + options.id.substr(1) + '"style="height: ' + options.height + 'px;"></svg>';
- }
-});
-
-});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/views/chart.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/views/chart.js
@@ -0,0 +1,204 @@
+// dependencies
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/chart', 'views/groups'],
+ function(Portlet, Table, Ui, Utils, Chart, GroupsView) {
+
+// widget
+return Backbone.View.extend(
+{
+ // defaults options
+ optionsDefault: {
+ header : true,
+ content : 'No content available.'
+ },
+
+ // initialize
+ initialize: function(app, options)
+ {
+ // link application
+ this.app = app;
+
+ // get current chart object
+ this.chart = this.app.chart;
+
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // main elements
+ this.message = new Ui.Message();
+ this.title = new Ui.Input({placeholder: 'Chart title'});
+ this.dataset = new Ui.Input({value : app.options.dataset.id, disabled: true, visible: false});
+
+ // configure dataset
+ this.groups_view = new GroupsView(this.app);
+
+ // table
+ var self = this;
+ this.table = new Table({
+ header : false,
+ onconfirm : function(type) {
+ if (self.chart.groups.length > 0) {
+ // show modal
+ self.app.modal.show({
+ title : 'Switching the chart type?',
+ body : 'You configured data sources. If you switch chart types your configurations will be removed.',
+ buttons : {
+ 'Cancel' : function() {
+ // hide modal
+ self.app.modal.hide();
+ },
+ 'Continue' : function() {
+ // hide modal
+ self.app.modal.hide();
+
+ // confirm
+ self.table.confirm(type);
+ }
+ }
+ });
+ } else {
+ // confirm
+ self.table.confirm(type);
+ }
+ },
+ onchange : function(type) {
+ // update chart type
+ self.chart.set({type: type});
+
+ // reset groups
+ self.chart.groups.reset();
+ },
+ content: 'No chart types available'
+ });
+
+ // add types
+ var types_n = 0;
+ var types = app.types.attributes;
+ for (var id in types){
+ var chart_type = types[id];
+ this.table.add (++types_n + '.');
+ this.table.add (chart_type.title);
+ this.table.append(id);
+ }
+
+ // add table to portlet
+ var self = this;
+ this.portlet = new Portlet({
+ icon : 'fa-edit',
+ label : 'Create a new chart:',
+ operations : {
+ 'save' : new Ui.ButtonIcon({
+ icon : 'fa-save',
+ tooltip : 'Save Chart',
+ onclick : function() {
+ self._saveChart();
+ }
+ }),
+ 'back' : new Ui.ButtonIcon({
+ icon : 'fa-caret-left',
+ tooltip : 'Return',
+ onclick : function() {
+ self.$el.hide();
+ self.app.charts_view.$el.show();
+ }
+ })
+ }
+ });
+ this.portlet.append(this.message.$el);
+ this.portlet.append(this.dataset.$el);
+ this.portlet.append((new Ui.Label({ label : 'Provide a chart title:'})).$el);
+ this.portlet.append(this.title.$el);
+ this.portlet.append((new Ui.Label({ label : 'Select a chart type:'})).$el);
+ this.portlet.append(this.table.$el);
+ this.portlet.append(this.groups_view.$el);
+
+ // elements
+ this.setElement(this.portlet.$el);
+
+ // hide back button on startup
+ this.portlet.hideOperation('back');
+
+ // model events
+ var self = this;
+ this.chart.on('change:title', function(chart) {
+ self.title.value(chart.get('title'));
+ });
+ this.chart.on('change:type', function(chart) {
+ self.table.value(chart.get('type'));
+ });
+
+ // collection events
+ this.app.charts.on('add', function(chart) {
+ self.portlet.showOperation('back');
+ });
+ this.app.charts.on('remove', function(chart) {
+ if (self.app.charts.length == 1) {
+ self.portlet.hideOperation('back');
+ }
+ });
+ this.app.charts.on('reset', function(chart) {
+ self.portlet.hideOperation('back');
+ });
+
+ // reset
+ this.reset();
+ },
+
+ // reset
+ reset: function() {
+ this.chart.reset();
+ this.chart.set('id', Utils.uuid());
+ this.chart.set('dataset_id', this.app.options.dataset.id);
+ this.chart.set('type', 'bardiagram');
+ this.chart.set('title', 'Chart title');
+ },
+
+ // set chart
+ setChart: function(new_chart) {
+ this.chart.copy(new_chart);
+ },
+
+ // create chart
+ _saveChart: function() {
+ // update chart data
+ this.chart.set({
+ type : this.table.value(),
+ title : this.title.value(),
+ dataset_id : this.dataset.value(),
+ date : Utils.time()
+ });
+
+ // validate
+ if (!this.chart.get('title')) {
+ this.message.update({message : 'Please enter a title for your chart.'});
+ return;
+ }
+
+ if (!this.chart.get('type')) {
+ this.message.update({message : 'Please select a chart type.'});
+ return;
+ }
+
+ if (this.chart.groups.length == 0) {
+ this.message.update({message : 'Please configure at least one data source.'});
+ return;
+ }
+
+ // create/get chart
+ var current = this.app.charts.get(this.chart.id);
+ if (!current) {
+ current = this.chart.clone();
+ this.app.charts.add(current);
+ }
+
+ // update chart model
+ current.copy(this.chart);
+
+ // hide
+ this.$el.hide();
+
+ // update main
+ this.app.charts_view.$el.show();
+ }
+});
+
+});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/views/charts.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/views/charts.js
@@ -0,0 +1,150 @@
+// dependencies
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils'], function(Portlet, Table, Ui, Utils) {
+
+// widget
+return Backbone.View.extend(
+{
+ // initialize
+ initialize: function(app, options)
+ {
+ // link app
+ this.app = app;
+
+ // table
+ this.table = new Table({
+ content : 'Add charts to this table.',
+ ondblclick : function(chart_id) {
+ // get chart
+ var chart = self.app.charts.get(chart_id);
+
+ // show edit
+ self.$el.hide();
+
+ // update model and show create
+ self.app.chart_view.setChart(chart);
+ self.app.chart_view.$el.show();
+ },
+ onchange : function(chart_id) {
+ self.app.viewport_view.show(chart_id);
+ }
+ });
+
+ // add table to portlet
+ var self = this;
+ this.portlet = new Portlet({
+ icon : 'fa-list',
+ label : 'List of created charts:',
+ height : 100,
+ operations : {
+ 'new' : new Ui.ButtonIcon({
+ icon : 'fa-plus',
+ tooltip: 'Create',
+ onclick: function() {
+ self.$el.hide();
+ self.app.chart_view.reset();
+ self.app.chart_view.$el.show();
+ }
+ }),
+ 'edit' : new Ui.ButtonIcon({
+ icon : 'fa-pencil',
+ tooltip: 'Edit',
+ onclick: function() {
+ // check if element has been selected
+ var chart_id = self.table.value();
+ if (!chart_id) {
+ return;
+ }
+
+ // get chart
+ var chart = self.app.charts.get(chart_id);
+
+ // show edit
+ self.$el.hide();
+ self.app.chart_view.$el.show();
+ self.app.chart_view.setChart(chart);
+ }
+ }),
+ 'delete' : new Ui.ButtonIcon({
+ icon : 'fa-minus',
+ tooltip: 'Delete',
+ onclick: function() {
+
+ // check if element has been selected
+ var chart_id = self.table.value();
+ if (!chart_id) {
+ return;
+ }
+
+ // title
+ var chart = self.app.charts.get(chart_id);
+
+ // show modal
+ self.app.modal.show({
+ title : 'Are you sure?',
+ body : 'The selected chart "' + chart.get('title') + '" will be irreversibly deleted.',
+ buttons : {
+ 'Cancel' : function() {self.app.modal.hide();},
+ 'Delete' : function() {
+ // hide modal
+ self.app.modal.hide();
+
+ // remove chart
+ self.app.charts.remove(chart_id);
+ }
+ }
+ });
+ }
+ }),
+ }
+ });
+ this.portlet.append(this.table.$el);
+
+ // append to main
+ this.$el.append(this.portlet.$el);
+
+ // events
+ var self = this;
+ this.app.charts.on('add', function(chart) {
+ // add
+ self._addChart(chart);
+ });
+ this.app.charts.on('remove', function(chart) {
+ // remove
+ self._removeChart(chart);
+ });
+ this.app.charts.on('change', function(chart) {
+ // replace
+ self._removeChart(chart);
+ self._addChart(chart);
+ });
+ },
+
+ // append
+ append : function($el) {
+ this.$el.append(Utils.wrap(''));
+ this.$el.append($el);
+ },
+
+ // add
+ _addChart: function(chart) {
+ // add title to table
+ this.table.add(chart.get('title'));
+
+ // get chart type
+ var type = this.app.types.get(chart.get('type'));
+ this.table.add(type.title);
+
+ // add additional columns
+ this.table.add('Last change: ' + chart.get('date'));
+ this.table.prepend(chart.get('id'));
+ this.table.value(chart.get('id'));
+ },
+
+ // remove
+ _removeChart: function(chart) {
+ // remove from to table
+ this.table.remove(chart.id);
+ }
+});
+
+});
\ No newline at end of file
diff -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 -r ee176b881f3784ab658254ff4d471bcd113f05ce config/plugins/visualizations/charts/static/views/group.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/views/group.js
@@ -0,0 +1,219 @@
+// dependencies
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/group'],
+ function(Portlet, Table, Ui, Utils, Group) {
+
+// chart config
+return Backbone.View.extend(
+{
+ // model
+ group: new Group(),
+
+ // columns
+ columns: [],
+
+ // initialize
+ initialize: function(app, options) {
+ // link app
+ this.app = app;
+
+ // get current chart object
+ this.chart = this.app.chart;
+
+ // ui elements
+ this.message = new Ui.Message();
+ this.label = new Ui.Input({placeholder: 'Group label'});
+ this.table = new Table({content: 'No data column.'});
+
+ // add table to portlet
+ var self = this;
+ this.portlet = new Portlet({
+ icon : 'fa-edit',
+ label : 'Define group properties:',
+ operations : {
+ 'save' : new Ui.ButtonIcon({
+ icon : 'fa-save',
+ tooltip : 'Save',
+ onclick : function() {
+ // save/add group
+ self._saveGroup();
+ }
+ }),
+ 'back' : new Ui.ButtonIcon({
+ icon : 'fa-caret-left',
+ tooltip : 'Return',
+ onclick : function() {
+ self.$el.hide();
+ self.app.chart_view.$el.show();
+ }
+ })
+ }
+ });
+ this.portlet.append(this.message.$el);
+ this.portlet.append(this.label.$el);
+ this.portlet.append(this.table.$el);
+
+ // add element
+ this.setElement(this.portlet.$el);
+
+ // change
+ var self = this;
+ this.chart.on('change:dataset_id', function() {
+ self._refreshDataset();
+ });
+ this.chart.on('change:type', function() {
+ self._refreshType();
+ });
+ this.group.on('change:label', function() {
+ self._refreshLabel();
+ });
+ this.group.on('change', function() {
+ self._refreshGroup();
+ });
+ },
+
+ // show
+ show: function() {
+ this.$el.show();
+ },
+
+ // reset
+ reset: function() {
+ this.group.reset();
+ this.group.set('id', Utils.uuid());
+ this.group.set('label', 'Group label');
+ },
+
+ // update dataset
+ _refreshDataset: function() {
+ // identify datasets
+ var dataset_id = this.chart.get('dataset_id');
+
+ // check if dataset is available
+ if (!dataset_id) {
+ return;
+ }
+
+ // get dataset
+ var dataset = this.app.datasets.get({id : dataset_id});
+
+ // check
+ if (!dataset) {
+ this.app.log('Config::render()', 'Failed to retrieve dataset.');
+ return;
+ }
+
+ // configure columns
+ this.columns = [];
+ var meta = dataset.metadata_column_types;
+ for (var key in meta){
+ this.columns.push({
+ 'label' : key + ' [' + meta[key] + ']',
+ 'value' : key
+ });
+ }
+
+ // update select fields
+ for (var key in this.list) {
+ this.list[key].update(this.columns);
+ }
+ },
+
+ // update
+ _refreshType: function() {
+ // configure chart type
+ var self = this;
+ var chart_type = this.chart.get('type');
+ if (chart_type) {
+ var chart_settings = this.app.types.get(chart_type);
+
+ // table
+ this.table.removeAll();
+ this.list = {};
+ for (var id in chart_settings.data) {
+ // create select field
+ var data_def = chart_settings.data[id];
+ var select = new Ui.Select({
+ id : 'select_' + id,
+ gid : id,
+ data : this.columns,
+ onchange : function(value) {
+ self.group.set(this.gid, value);
+ }
+ });
+
+ // add row to table
+ this.table.add(data_def.title);
+ this.table.add(select.$el);
+ this.table.append(id);
+
+ // add select field to list
+ this.list[id] = select;
+ }
+ }
+ },
+
+ // update
+ _refreshGroup: function() {
+ // update select fields
+ for (var id in this.list) {
+ var col = this.group.get(id);
+ if (col === undefined) {
+ col = 0;
+ }
+ this.list[id].value(col);
+ }
+ },
+
+ // update label
+ _refreshLabel: function() {
+ var label_text = this.group.get('label');
+ if (label_text === undefined) {
+ label_text = '';
+ }
+ this.label.value(label_text);
+ },
+
+ // create group
+ _saveGroup: function() {
+ // get current chart
+ var chart = this.chart;
+
+ // update group object
+ var group = this.group;
+ for (var key in this.list) {
+ group.set(key, this.list[key].value());
+ }
+
+ // add label
+ group.set({
+ dataset_id : this.chart.get('dataset_id'),
+ label : this.label.value(),
+ date : Utils.time()
+ });
+
+ // validate
+ if (!group.get('label')) {
+ this.message.update({message : 'Please enter a label for your group.'});
+ return;
+ }
+
+ // get groups of current chart
+ var groups = this.chart.groups;
+
+ // create/update group
+ var group_update = groups.get(group.id);
+ if (group_update) {
+ group_update.set(group.attributes);
+ } else {
+ groups.add(group.clone());
+ }
+
+ // hide
+ this.$el.hide();
+
+ // update main
+ this.app.chart_view.$el.show();
+ }
+});
+
+});
\ No newline at end of file
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: inithello: Fix deletion of test methods after tests have been run.
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/7b889da9b563/
Changeset: 7b889da9b563
User: inithello
Date: 2014-01-16 17:30:25
Summary: Fix deletion of test methods after tests have been run.
Affected #: 3 files
diff -r 659a29d112f622db5dabb65e4105535b5aee3b30 -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 scripts/functional_tests.py
--- a/scripts/functional_tests.py
+++ b/scripts/functional_tests.py
@@ -498,6 +498,7 @@
functional.test_toolbox.toolbox = app.toolbox
# When testing data managers, do not test toolbox.
functional.test_toolbox.build_tests(
+ app=app,
testing_shed_tools=testing_shed_tools,
master_api_key=master_api_key,
user_api_key=get_user_api_key(),
diff -r 659a29d112f622db5dabb65e4105535b5aee3b30 -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 test/functional/test_toolbox.py
--- a/test/functional/test_toolbox.py
+++ b/test/functional/test_toolbox.py
@@ -72,13 +72,13 @@
raise
-def build_tests( testing_shed_tools=False, master_api_key=None, user_api_key=None ):
+def build_tests( app=None, testing_shed_tools=False, master_api_key=None, user_api_key=None ):
"""
If the module level variable `toolbox` is set, generate `ToolTestCase`
classes for all of its tests and put them into this modules globals() so
they can be discovered by nose.
"""
- if toolbox is None:
+ if app is None:
return
# Push all the toolbox tests to module level
@@ -88,9 +88,8 @@
for key, val in G.items():
if key.startswith( 'TestForTool_' ):
del G[ key ]
-
- for i, tool_id in enumerate( toolbox.tools_by_id ):
- tool = toolbox.get_tool( tool_id )
+ for i, tool_id in enumerate( app.toolbox.tools_by_id ):
+ tool = app.toolbox.get_tool( tool_id )
if isinstance( tool, TOOL_TYPES_NO_TEST ):
#We do not test certain types of tools (e.g. Data Manager tools) as part of ToolTestCase
continue
diff -r 659a29d112f622db5dabb65e4105535b5aee3b30 -r 7b889da9b563bc8245977dceb5aa4b8965857aa2 test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
--- a/test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
+++ b/test/install_and_test_tool_shed_repositories/repositories_with_tools/functional_tests.py
@@ -595,21 +595,16 @@
"""
tests_to_delete = []
tools_to_delete_by_id = []
- # Push all the toolbox tests to module level
- G = globals()
- # Eliminate all previous tests from G.
- for key, val in G.items():
- if key.startswith( 'TestForTool_' ):
- del G[ key ]
- # Find all tests previously generated by twill.
for key in test_toolbox.__dict__:
if key.startswith( 'TestForTool_' ):
- log.debug( 'Tool test %s discovered in test_toolbox.' % str( key ) )
# We can't delete this test just yet, we're still iterating over __dict__.
tests_to_delete.append( key )
tool_id = key.replace( 'TestForTool_', '' )
for app_tool_id in app.toolbox.tools_by_id:
- if app_tool_id.replace( '_', ' ' ) == tool_id.replace( '_', ' ' ):
+ # Revisit this code if at some point we notice that Twill re-runs tests that should have been deleted.
+ # Undoubtedly the following if statement will need to be enhanced to find the tool id in question. For
+ # example, the following or is required because Twill replaces some spaces with underscores in test names.
+ if app_tool_id == tool_id or app_tool_id.replace( '_', ' ' ) == tool_id.replace( '_', ' ' ):
tools_to_delete_by_id.append( tool_id )
# Delete the discovered twill-generated tests.
for key in tests_to_delete:
@@ -617,16 +612,12 @@
log.debug( 'Deleting test %s from test_toolbox.' % str( key ) )
del test_toolbox.__dict__[ key ]
for tool_id in tools_to_delete_by_id:
- if tool_id in app.toolbox.tools_by_id:
- log.debug( 'Deleting tool id %s from app.toolbox[ tools_by_id ].' % str( tool_id ) )
- del app.toolbox.tools_by_id[ tool_id ]
+ log.debug( 'Deleting tool id %s from app.toolbox[ tools_by_id ].' % str( tool_id ) )
+ del app.toolbox.tools_by_id[ tool_id ]
def test_repository_tools( app, repository, repository_dict, tool_test_results_dicts, tool_test_results_dict,
install_and_test_statistics_dict ):
"""Test tools contained in the received repository."""
- # Set the global variable 'test_toolbox', so that test.functional.test_toolbox will generate the
- # appropriate test methods.
- test_toolbox.toolbox = app.toolbox
# Get the attributes that identify the repository whose contained tools are being tested.
name = str( repository.name )
owner = str( repository.owner )
@@ -635,7 +626,8 @@
# Generate the test methods for this installed repository. We need to pass testing_shed_tools=True here
# or twill will look in $GALAXY_HOME/test-data for test data, which may result in missing or invalid test
# files.
- test_toolbox.build_tests( testing_shed_tools=True,
+ test_toolbox.build_tests( app=app,
+ testing_shed_tools=True,
master_api_key=install_and_test_base_util.default_galaxy_master_api_key )
# Set up nose to run the generated functional tests.
test_config = nose.config.Config( env=os.environ, plugins=nose.plugins.manager.DefaultPluginManager() )
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4f1f6bb5bf5e/
Changeset: 4f1f6bb5bf5e
User: jmchilton
Date: 2014-01-16 16:30:01
Summary: Add tool execution tests for various exceptional conditions.
Tool action raising exception, redirecting, and returning an error message.
Affected #: 1 file
diff -r ff018b067bb21760335de776f7e97a987d86c7e6 -r 4f1f6bb5bf5e975f4d40a8feeeed77795a6d69aa test/unit/tools/test_execution.py
--- a/test/unit/tools/test_execution.py
+++ b/test/unit/tools/test_execution.py
@@ -15,6 +15,10 @@
from galaxy.util.odict import odict
from tools_support import UsesApp
+from galaxy import eggs
+eggs.require( "Paste" )
+from paste import httpexceptions
+
# Simple tool with just one text parameter and output.
SIMPLE_TOOL_CONTENTS = '''<tool id="test_tool" name="Test Tool"><command>echo "$param1" < $out1</command>
@@ -92,6 +96,41 @@
# Didn't specify a rerun_remap_id so this should be None
assert self.tool_action.execution_call_args[ 0 ][ "rerun_remap_job_id" ] is None
+ def test_execute_exception( self ):
+ self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self.tool_action.raise_exception( )
+ template, template_vars = self.__handle_with_incoming(
+ param1="moo",
+ runtool_btn="dummy",
+ )
+ assert template == "message.mako"
+ assert template_vars[ "status" ] == "error"
+ assert "Error executing tool" in template_vars[ "message" ]
+
+ def test_execute_errors( self ):
+ self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self.tool_action.return_error( )
+ template, template_vars = self.__handle_with_incoming(
+ param1="moo",
+ runtool_btn="dummy",
+ )
+ assert template == "message.mako"
+ assert template_vars[ "status" ] == "error"
+ assert "Test Error Message" in template_vars[ "message" ], template_vars
+
+ def test_redirect( self ):
+ self.__init_tool( SIMPLE_TOOL_CONTENTS )
+ self.tool_action.expect_redirect = True
+ redirect_raised = False
+ try:
+ template, template_vars = self.__handle_with_incoming(
+ param1="moo",
+ runtool_btn="dummy",
+ )
+ except httpexceptions.HTTPFound:
+ redirect_raised = True
+ assert redirect_raised
+
def test_remap_job( self ):
self.__init_tool( SIMPLE_TOOL_CONTENTS )
template, template_vars = self.__handle_with_incoming(
@@ -237,12 +276,31 @@
def __init__( self, expected_trans ):
self.expected_trans = expected_trans
self.execution_call_args = []
+ self.expect_redirect = False
+ self.exception_after_exection = None
+ self.error_message_after_excution = None
def execute( self, tool, trans, **kwds ):
assert self.expected_trans == trans
self.execution_call_args.append( kwds )
+ num_calls = len( self.execution_call_args )
+ if self.expect_redirect:
+ raise httpexceptions.HTTPFound( "http://google.com" )
+ if self.exception_after_exection is not None:
+ if num_calls > self.exception_after_exection:
+ raise Exception( "Test Exception" )
+ if self.error_message_after_excution is not None:
+ if num_calls > self.error_message_after_excution:
+ return None, "Test Error Message"
+
return None, odict(dict(out1="1"))
+ def raise_exception( self, after_execution=0 ):
+ self.exception_after_exection = after_execution
+
+ def return_error( self, after_execution=0 ):
+ self.error_message_after_excution = after_execution
+
class MockTrans( object ):
https://bitbucket.org/galaxy/galaxy-central/commits/659a29d112f6/
Changeset: 659a29d112f6
User: jmchilton
Date: 2014-01-16 16:30:01
Summary: Rearrange __handle_execute and handle_input in Tool...
Slightly cleaner this way (fewer exit points) and will enable extensions I am making downstream.
Affected #: 1 file
diff -r 4f1f6bb5bf5e975f4d40a8feeeed77795a6d69aa -r 659a29d112f622db5dabb65e4105535b5aee3b30 lib/galaxy/tools/__init__.py
--- a/lib/galaxy/tools/__init__.py
+++ b/lib/galaxy/tools/__init__.py
@@ -1871,7 +1871,7 @@
errors, params = self.__check_param_values( trans, incoming, state, old_errors, process_state, history=history, source=source )
if self.__should_refresh_state( incoming ):
- return self.__handle_state_refresh( trans, state, errors )
+ template, template_vars = self.__handle_state_refresh( trans, state, errors )
else:
# User actually clicked next or execute.
@@ -1879,18 +1879,30 @@
# error messages
if errors:
error_message = "One or more errors were found in the input you provided. The specific errors are marked below."
- return "tool_form.mako", dict( errors=errors, tool_state=state, incoming=incoming, error_message=error_message )
+ template = "tool_form.mako"
+ template_vars = dict( errors=errors, tool_state=state, incoming=incoming, error_message=error_message )
# If we've completed the last page we can execute the tool
elif all_pages or state.page == self.last_page:
- return self.__handle_tool_execute( trans, rerun_remap_job_id, params, history )
+ tool_executed, result = self.__handle_tool_execute( trans, rerun_remap_job_id, params, history )
+ if tool_executed:
+ template = 'tool_executed.mako'
+ template_vars = dict( out_data=result )
+ else:
+ template = 'message.mako'
+ template_vars = dict( status='error', message=result, refresh_frames=[] )
# Otherwise move on to the next page
else:
- return self.__handle_page_advance( trans, state, errors )
+ template, template_vars = self.__handle_page_advance( trans, state, errors )
+ return template, template_vars
def __should_refresh_state( self, incoming ):
return not( 'runtool_btn' in incoming or 'URL' in incoming or 'ajax_upload' in incoming )
def __handle_tool_execute( self, trans, rerun_remap_job_id, params, history ):
+ """
+ Return a pair with whether execution is successful as well as either
+ resulting output data or an error message indicating the problem.
+ """
try:
_, out_data = self.execute( trans, incoming=params, history=history, rerun_remap_job_id=rerun_remap_job_id )
except httpexceptions.HTTPFound, e:
@@ -1898,16 +1910,16 @@
raise e
except Exception, e:
log.exception('Exception caught while attempting tool execution:')
- return 'message.mako', dict( status='error', message='Error executing tool: %s' % str(e), refresh_frames=[] )
- try:
- assert isinstance( out_data, odict )
- return 'tool_executed.mako', dict( out_data=out_data )
- except:
+ message = 'Error executing tool: %s' % str(e)
+ return False, message
+ if isinstance( out_data, odict ):
+ return True, out_data
+ else:
if isinstance( out_data, str ):
message = out_data
else:
- message = 'Failure executing tool (odict not returned from tool execution)'
- return 'message.mako', dict( status='error', message=message, refresh_frames=[] )
+ message = 'Failure executing tool (invalid data returned from tool execution)'
+ return False, message
def __handle_state_refresh( self, trans, state, errors ):
try:
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: dannon: Explicitly require UsesAnnotations mixin for the annotations api controller *after* UsesStoredWorkflowMixin.
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/ff018b067bb2/
Changeset: ff018b067bb2
User: dannon
Date: 2014-01-16 15:56:31
Summary: Explicitly require UsesAnnotations mixin for the annotations api controller *after* UsesStoredWorkflowMixin.
Affected #: 1 file
diff -r 2f7781fc4ce9dbb1768fd345621ec2a62000f2ae -r ff018b067bb21760335de776f7e97a987d86c7e6 lib/galaxy/webapps/galaxy/api/annotations.py
--- a/lib/galaxy/webapps/galaxy/api/annotations.py
+++ b/lib/galaxy/webapps/galaxy/api/annotations.py
@@ -3,13 +3,14 @@
"""
import logging
from galaxy import web
+from galaxy.model.item_attrs import UsesAnnotations
from galaxy.util.sanitize_html import sanitize_html
from galaxy.web.base.controller import BaseAPIController, HTTPNotImplemented, UsesHistoryDatasetAssociationMixin, UsesHistoryMixin, UsesStoredWorkflowMixin
log = logging.getLogger( __name__ )
-class BaseAnnotationsController( BaseAPIController, UsesHistoryMixin, UsesHistoryDatasetAssociationMixin, UsesStoredWorkflowMixin ):
+class BaseAnnotationsController( BaseAPIController, UsesHistoryMixin, UsesHistoryDatasetAssociationMixin, UsesStoredWorkflowMixin, UsesAnnotations ):
@web.expose_api
def index( self, trans, **kwd ):
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
5 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/315465b38434/
Changeset: 315465b38434
User: nsoranzo
Date: 2014-01-15 17:51:36
Summary: PEP-8 and unused variables fixes.
Affected #: 1 file
diff -r 8deba81aad81fd565a7e33bad10bb8e741a6172b -r 315465b38434aff44e8863c6f2ea7e9ab549beb2 lib/galaxy/webapps/galaxy/api/workflows.py
--- a/lib/galaxy/webapps/galaxy/api/workflows.py
+++ b/lib/galaxy/webapps/galaxy/api/workflows.py
@@ -241,7 +241,7 @@
outputs = util.odict.odict()
rval['history'] = trans.security.encode_id(history.id)
rval['outputs'] = []
- for i, step in enumerate( workflow.steps ):
+ for step in workflow.steps:
job = None
if step.type == 'tool' or step.type is None:
tool = self.app.toolbox.get_tool( step.tool_id )
@@ -285,7 +285,7 @@
"""
try:
stored_workflow = trans.sa_session.query(self.app.model.StoredWorkflow).get(trans.security.decode_id(workflow_id))
- except Exception,e:
+ except Exception, e:
return ("Workflow with ID='%s' can not be found\n Exception: %s") % (workflow_id, str( e ))
# check to see if user has permissions to selected workflow
if stored_workflow.user != trans.user and not trans.user_is_admin():
@@ -293,7 +293,7 @@
trans.response.status = 400
return("Workflow is not owned by or shared with current user")
- ret_dict = self._workflow_to_dict( trans, stored_workflow );
+ ret_dict = self._workflow_to_dict( trans, stored_workflow )
if not ret_dict:
#This workflow has a tool that's missing from the distribution
trans.response.status = 400
@@ -309,7 +309,7 @@
copied from galaxy.web.controllers.workflows.py (delete)
"""
- workflow_id = id;
+ workflow_id = id
try:
stored_workflow = trans.sa_session.query(self.app.model.StoredWorkflow).get(trans.security.decode_id(workflow_id))
@@ -341,23 +341,23 @@
# currently assumes payload['workflow'] is a json representation of a workflow to be inserted into the database
"""
- data = payload['workflow'];
+ data = payload['workflow']
workflow, missing_tool_tups = self._workflow_from_dict( trans, data, source="API" )
# galaxy workflow newly created id
- workflow_id = workflow.id;
+ workflow_id = workflow.id
# api encoded, id
- encoded_id = trans.security.encode_id(workflow_id);
+ encoded_id = trans.security.encode_id(workflow_id)
# return list
- rval= [];
+ rval = []
item = workflow.to_dict(value_mapper={'id':trans.security.encode_id})
item['url'] = url_for('workflow', id=encoded_id)
- rval.append(item);
+ rval.append(item)
- return item;
+ return item
def _workflow_from_dict( self, trans, data, source=None ):
"""
@@ -386,7 +386,7 @@
# will be ( tool_id, tool_name, tool_version ).
missing_tool_tups = []
# First pass to build step objects and populate basic values
- for key, step_dict in data[ 'steps' ].iteritems():
+ for step_dict in data[ 'steps' ].itervalues():
# Create the model class for the step
step = model.WorkflowStep()
steps.append( step )
@@ -530,7 +530,7 @@
step_dict['inputs'].append( { "name" : name, "description" : "runtime parameter for tool %s" % module.get_name() } )
elif input_type == dict:
# Input type is described by a dict, e.g. indexed parameters.
- for partname, partval in val.items():
+ for partval in val.values():
if type( partval ) == RuntimeValue:
step_dict['inputs'].append( { "name" : name, "description" : "runtime parameter for tool %s" % module.get_name() } )
# User outputs
https://bitbucket.org/galaxy/galaxy-central/commits/4fb2ce004601/
Changeset: 4fb2ce004601
User: nsoranzo
Date: 2014-01-15 18:04:33
Summary: Let /api/workflows show() method display also importable workflows.
Affected #: 1 file
diff -r 315465b38434aff44e8863c6f2ea7e9ab549beb2 -r 4fb2ce004601f50d63c4884006d453eee580a85a lib/galaxy/webapps/galaxy/api/workflows.py
--- a/lib/galaxy/webapps/galaxy/api/workflows.py
+++ b/lib/galaxy/webapps/galaxy/api/workflows.py
@@ -60,10 +60,10 @@
return "Malformed workflow id ( %s ) specified, unable to decode." % str(workflow_id)
try:
stored_workflow = trans.sa_session.query(trans.app.model.StoredWorkflow).get(decoded_workflow_id)
- if stored_workflow.user != trans.user and not trans.user_is_admin():
+ if stored_workflow.importable == False and stored_workflow.user != trans.user and not trans.user_is_admin():
if trans.sa_session.query(trans.app.model.StoredWorkflowUserShareAssociation).filter_by(user=trans.user, stored_workflow=stored_workflow).count() == 0:
trans.response.status = 400
- return("Workflow is not owned by or shared with current user")
+ return("Workflow is neither importable, nor owned by or shared with current user")
except:
trans.response.status = 400
return "That workflow does not exist."
https://bitbucket.org/galaxy/galaxy-central/commits/33af32773cba/
Changeset: 33af32773cba
User: nsoranzo
Date: 2014-01-15 18:22:51
Summary: Add show_published param to /api/workflows index() method to display also published workflows.
Affected #: 1 file
diff -r 4fb2ce004601f50d63c4884006d453eee580a85a -r 33af32773cba309fde44ced5fba78ce8fc64078b lib/galaxy/webapps/galaxy/api/workflows.py
--- a/lib/galaxy/webapps/galaxy/api/workflows.py
+++ b/lib/galaxy/webapps/galaxy/api/workflows.py
@@ -5,7 +5,7 @@
"""
import logging
-from sqlalchemy import desc
+from sqlalchemy import desc, or_
from galaxy import util
from galaxy import web
from galaxy import model
@@ -26,10 +26,17 @@
GET /api/workflows
Displays a collection of workflows.
+
+ :param show_published: if True, show also published workflows
+ :type show_published: boolean
"""
+ show_published = util.string_as_bool( kwd.get( 'show_published', 'False' ) )
rval = []
- for wf in trans.sa_session.query(trans.app.model.StoredWorkflow).filter_by(
- user=trans.user, deleted=False).order_by(
+ filter1 = ( trans.app.model.StoredWorkflow.user == trans.user )
+ if show_published:
+ filter1 = or_( filter1, ( trans.app.model.StoredWorkflow.published == True ) )
+ for wf in trans.sa_session.query(trans.app.model.StoredWorkflow).filter(
+ filter1, trans.app.model.StoredWorkflow.table.c.deleted == False ).order_by(
desc(trans.app.model.StoredWorkflow.table.c.update_time)).all():
item = wf.to_dict(value_mapper={'id':trans.security.encode_id})
encoded_id = trans.security.encode_id(wf.id)
https://bitbucket.org/galaxy/galaxy-central/commits/f4be6a4360b6/
Changeset: f4be6a4360b6
User: nsoranzo
Date: 2014-01-15 18:17:24
Summary: Move core code for importing a shared workflow to UsesStoredWorkflowMixin.
Affected #: 4 files
diff -r 33af32773cba309fde44ced5fba78ce8fc64078b -r f4be6a4360b6c8c12f7eeed363c0dfe29dc8db41 lib/galaxy/web/base/controller.py
--- a/lib/galaxy/web/base/controller.py
+++ b/lib/galaxy/web/base/controller.py
@@ -33,7 +33,7 @@
from galaxy.model.orm import eagerload, eagerload_all, desc
from galaxy.security.validate_user_input import validate_publicname
from galaxy.util.sanitize_html import sanitize_html
-from galaxy.model.item_attrs import Dictifiable
+from galaxy.model.item_attrs import Dictifiable, UsesAnnotations
from galaxy.datatypes.interval import ChromatinInteractions
from galaxy.datatypes.data import Text
@@ -1497,7 +1497,7 @@
return return_message
-class UsesStoredWorkflowMixin( SharableItemSecurityMixin ):
+class UsesStoredWorkflowMixin( SharableItemSecurityMixin, UsesAnnotations ):
""" Mixin for controllers that use StoredWorkflow objects. """
def get_stored_workflow( self, trans, id, check_ownership=True, check_accessible=False ):
@@ -1539,6 +1539,26 @@
# Connections by input name
step.input_connections_by_name = dict( ( conn.input_name, conn ) for conn in step.input_connections )
+ def _import_shared_workflow( self, trans, stored):
+ """ """
+ # Copy workflow.
+ imported_stored = model.StoredWorkflow()
+ imported_stored.name = "imported: " + stored.name
+ imported_stored.latest_workflow = stored.latest_workflow
+ imported_stored.user = trans.user
+ # Save new workflow.
+ session = trans.sa_session
+ session.add( imported_stored )
+ session.flush()
+
+ # Copy annotations.
+ self.copy_item_annotation( session, stored.user, stored, imported_stored.user, imported_stored )
+ for order_index, step in enumerate( stored.latest_workflow.steps ):
+ self.copy_item_annotation( session, stored.user, step, \
+ imported_stored.user, imported_stored.latest_workflow.steps[order_index] )
+ session.flush()
+ return imported_stored
+
class UsesFormDefinitionsMixin:
"""Mixin for controllers that use Galaxy form objects."""
diff -r 33af32773cba309fde44ced5fba78ce8fc64078b -r f4be6a4360b6c8c12f7eeed363c0dfe29dc8db41 lib/galaxy/webapps/galaxy/api/annotations.py
--- a/lib/galaxy/webapps/galaxy/api/annotations.py
+++ b/lib/galaxy/webapps/galaxy/api/annotations.py
@@ -3,14 +3,13 @@
"""
import logging
from galaxy import web
-from galaxy.model.item_attrs import UsesAnnotations
from galaxy.util.sanitize_html import sanitize_html
from galaxy.web.base.controller import BaseAPIController, HTTPNotImplemented, UsesHistoryDatasetAssociationMixin, UsesHistoryMixin, UsesStoredWorkflowMixin
log = logging.getLogger( __name__ )
-class BaseAnnotationsController( BaseAPIController, UsesAnnotations, UsesHistoryMixin, UsesHistoryDatasetAssociationMixin, UsesStoredWorkflowMixin ):
+class BaseAnnotationsController( BaseAPIController, UsesHistoryMixin, UsesHistoryDatasetAssociationMixin, UsesStoredWorkflowMixin ):
@web.expose_api
def index( self, trans, **kwd ):
diff -r 33af32773cba309fde44ced5fba78ce8fc64078b -r f4be6a4360b6c8c12f7eeed363c0dfe29dc8db41 lib/galaxy/webapps/galaxy/controllers/page.py
--- a/lib/galaxy/webapps/galaxy/controllers/page.py
+++ b/lib/galaxy/webapps/galaxy/controllers/page.py
@@ -1,7 +1,7 @@
from sqlalchemy import desc, and_
from galaxy import model, web
from galaxy.web import error, url_for
-from galaxy.model.item_attrs import UsesAnnotations, UsesItemRatings
+from galaxy.model.item_attrs import UsesItemRatings
from galaxy.web.base.controller import BaseUIController, SharableMixin, UsesHistoryMixin, UsesStoredWorkflowMixin, UsesVisualizationMixin
from galaxy.web.framework.helpers import time_ago, grids
from galaxy import util
@@ -274,7 +274,7 @@
# Default behavior:
_BaseHTMLProcessor.unknown_endtag( self, tag )
-class PageController( BaseUIController, SharableMixin, UsesAnnotations, UsesHistoryMixin,
+class PageController( BaseUIController, SharableMixin, UsesHistoryMixin,
UsesStoredWorkflowMixin, UsesVisualizationMixin, UsesItemRatings ):
_page_list = PageListGrid()
diff -r 33af32773cba309fde44ced5fba78ce8fc64078b -r f4be6a4360b6c8c12f7eeed363c0dfe29dc8db41 lib/galaxy/webapps/galaxy/controllers/workflow.py
--- a/lib/galaxy/webapps/galaxy/controllers/workflow.py
+++ b/lib/galaxy/webapps/galaxy/controllers/workflow.py
@@ -19,7 +19,7 @@
from galaxy import web
from galaxy.datatypes.data import Data
from galaxy.jobs.actions.post import ActionBox
-from galaxy.model.item_attrs import UsesAnnotations, UsesItemRatings
+from galaxy.model.item_attrs import UsesItemRatings
from galaxy.model.mapping import desc
from galaxy.tools.parameters import RuntimeValue, visit_input_values
from galaxy.tools.parameters.basic import DataToolParameter, DrillDownSelectToolParameter, SelectToolParameter, UnvalidatedValue
@@ -132,7 +132,7 @@
self.tag_content += text
-class WorkflowController( BaseUIController, SharableMixin, UsesStoredWorkflowMixin, UsesAnnotations, UsesItemRatings ):
+class WorkflowController( BaseUIController, SharableMixin, UsesStoredWorkflowMixin, UsesItemRatings ):
stored_list_grid = StoredWorkflowListGrid()
published_list_grid = StoredWorkflowAllPublishedGrid()
@@ -372,34 +372,17 @@
referer_message = "<a href='%s'>go to Galaxy's start page</a>" % url_for( '/' )
# Do import.
- session = trans.sa_session
stored = self.get_stored_workflow( trans, id, check_ownership=False )
if stored.importable == False:
return trans.show_error_message( "The owner of this workflow has disabled imports via this link.<br>You can %s" % referer_message, use_panels=True )
elif stored.deleted:
return trans.show_error_message( "You can't import this workflow because it has been deleted.<br>You can %s" % referer_message, use_panels=True )
- else:
- # Copy workflow.
- imported_stored = model.StoredWorkflow()
- imported_stored.name = "imported: " + stored.name
- imported_stored.latest_workflow = stored.latest_workflow
- imported_stored.user = trans.user
- # Save new workflow.
- session = trans.sa_session
- session.add( imported_stored )
- session.flush()
+ self._import_shared_workflow( trans, stored )
- # Copy annotations.
- self.copy_item_annotation( session, stored.user, stored, imported_stored.user, imported_stored )
- for order_index, step in enumerate( stored.latest_workflow.steps ):
- self.copy_item_annotation( session, stored.user, step, \
- imported_stored.user, imported_stored.latest_workflow.steps[order_index] )
- session.flush()
-
- # Redirect to load galaxy frames.
- return trans.show_ok_message(
- message="""Workflow "%s" has been imported. <br>You can <a href="%s">start using this workflow</a> or %s."""
- % ( stored.name, web.url_for( controller='workflow' ), referer_message ), use_panels=True )
+ # Redirect to load galaxy frames.
+ return trans.show_ok_message(
+ message="""Workflow "%s" has been imported. <br>You can <a href="%s">start using this workflow</a> or %s."""
+ % ( stored.name, web.url_for( controller='workflow' ), referer_message ), use_panels=True )
@web.expose
@web.require_login( "use Galaxy workflows" )
https://bitbucket.org/galaxy/galaxy-central/commits/2f7781fc4ce9/
Changeset: 2f7781fc4ce9
User: nsoranzo
Date: 2014-01-15 18:28:21
Summary: Add /api/workflows/import method to import a workflow shared by other users.
Affected #: 2 files
diff -r f4be6a4360b6c8c12f7eeed363c0dfe29dc8db41 -r 2f7781fc4ce9dbb1768fd345621ec2a62000f2ae lib/galaxy/webapps/galaxy/api/workflows.py
--- a/lib/galaxy/webapps/galaxy/api/workflows.py
+++ b/lib/galaxy/webapps/galaxy/api/workflows.py
@@ -6,20 +6,21 @@
import logging
from sqlalchemy import desc, or_
+from galaxy import exceptions
from galaxy import util
from galaxy import web
from galaxy import model
from galaxy.tools.parameters import visit_input_values, DataToolParameter, RuntimeValue
-from galaxy.web.base.controller import BaseAPIController, url_for
+from galaxy.web import _future_expose_api as expose_api
+from galaxy.web.base.controller import BaseAPIController, url_for, UsesStoredWorkflowMixin
from galaxy.workflow.modules import module_factory, ToolModule
from galaxy.jobs.actions.post import ActionBox
-from galaxy.model.item_attrs import UsesAnnotations
from ..controllers.workflow import attach_ordered_steps
log = logging.getLogger(__name__)
-class WorkflowsAPIController(BaseAPIController, UsesAnnotations):
+class WorkflowsAPIController(BaseAPIController, UsesStoredWorkflowMixin):
@web.expose_api
def index(self, trans, **kwd):
"""
@@ -584,3 +585,31 @@
data['steps'][step.order_index] = step_dict
return data
+ @expose_api
+ def import_shared_worflow(self, trans, payload, **kwd):
+ """
+ POST /api/workflows/import
+ Import a workflow shared by other users.
+
+ :param workflow_id: the workflow id (required)
+ :type workflow_id: str
+
+ :raises: exceptions.MessageException, exceptions.ObjectNotFound
+ """
+ # Pull parameters out of payload.
+ workflow_id = payload.get('workflow_id', None)
+ if workflow_id == None:
+ raise exceptions.ObjectAttributeMissingException( "Missing required parameter 'workflow_id'." )
+ try:
+ stored_workflow = self.get_stored_workflow( trans, workflow_id, check_ownership=False )
+ except:
+ raise exceptions.ObjectNotFound( "Malformed workflow id ( %s ) specified." % workflow_id )
+ if stored_workflow.importable == False:
+ raise exceptions.MessageException( 'The owner of this workflow has disabled imports via this link.' )
+ elif stored_workflow.deleted:
+ raise exceptions.MessageException( "You can't import this workflow because it has been deleted." )
+ imported_workflow = self._import_shared_workflow( trans, stored_workflow )
+ item = imported_workflow.to_dict(value_mapper={'id':trans.security.encode_id})
+ encoded_id = trans.security.encode_id(imported_workflow.id)
+ item['url'] = url_for('workflow', id=encoded_id)
+ return item
diff -r f4be6a4360b6c8c12f7eeed363c0dfe29dc8db41 -r 2f7781fc4ce9dbb1768fd345621ec2a62000f2ae lib/galaxy/webapps/galaxy/buildapp.py
--- a/lib/galaxy/webapps/galaxy/buildapp.py
+++ b/lib/galaxy/webapps/galaxy/buildapp.py
@@ -163,10 +163,11 @@
# "POST /api/workflows/import" => ``workflows.import_workflow()``.
# Defines a named route "import_workflow".
- webapp.mapper.connect("import_workflow", "/api/workflows/upload", controller="workflows", action="import_new_workflow", conditions=dict(method=["POST"]))
- webapp.mapper.connect("workflow_dict", '/api/workflows/{workflow_id}/download', controller='workflows', action='workflow_dict', conditions=dict(method=['GET']))
+ webapp.mapper.connect( 'import_workflow', '/api/workflows/upload', controller='workflows', action='import_new_workflow', conditions=dict( method=['POST'] ) )
+ webapp.mapper.connect( 'workflow_dict', '/api/workflows/{workflow_id}/download', controller='workflows', action='workflow_dict', conditions=dict( method=['GET'] ) )
# Preserve the following download route for now for dependent applications -- deprecate at some point
- webapp.mapper.connect("workflow_dict", '/api/workflows/download/{workflow_id}', controller='workflows', action='workflow_dict', conditions=dict(method=['GET']))
+ webapp.mapper.connect( 'workflow_dict', '/api/workflows/download/{workflow_id}', controller='workflows', action='workflow_dict', conditions=dict( method=['GET'] ) )
+ webapp.mapper.connect( 'import_shared_workflow', '/api/workflows/import', controller='workflows', action='import_shared_worflow', conditions=dict( method=['POST'] ) )
# =======================
# ===== LIBRARY API =====
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: guerler: Charts: Improve button selection
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/8deba81aad81/
Changeset: 8deba81aad81
User: guerler
Date: 2014-01-16 07:38:06
Summary: Charts: Improve button selection
Affected #: 4 files
diff -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 -r 8deba81aad81fd565a7e33bad10bb8e741a6172b config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -48,9 +48,6 @@
// set elements
this.setElement(this.portlet.$el);
-
- // reset create view
- this.create.reset();
},
// execute command
diff -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 -r 8deba81aad81fd565a7e33bad10bb8e741a6172b config/plugins/visualizations/charts/static/create.js
--- a/config/plugins/visualizations/charts/static/create.js
+++ b/config/plugins/visualizations/charts/static/create.js
@@ -97,8 +97,8 @@
}
}),
'back' : new Ui.ButtonIcon({
- icon : 'fa-list',
- tooltip : 'Show Charts',
+ icon : 'fa-caret-left',
+ tooltip : 'Return',
onclick : function() {
self.$el.hide();
self.app.main.$el.show();
@@ -117,7 +117,10 @@
// elements
this.setElement(this.portlet.$el);
- // events
+ // hide back button on startup
+ this.portlet.hideOperation('back');
+
+ // model events
var self = this;
this.chart.on('change:title', function(chart) {
self.title.value(chart.get('title'));
@@ -125,6 +128,22 @@
this.chart.on('change:type', function(chart) {
self.table.value(chart.get('type'));
});
+
+ // collection events
+ this.app.charts.on('add', function(chart) {
+ self.portlet.showOperation('back');
+ });
+ this.app.charts.on('remove', function(chart) {
+ if (self.app.charts.length == 1) {
+ self.portlet.hideOperation('back');
+ }
+ });
+ this.app.charts.on('reset', function(chart) {
+ self.portlet.hideOperation('back');
+ });
+
+ // reset
+ this.reset();
},
// reset
diff -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 -r 8deba81aad81fd565a7e33bad10bb8e741a6172b config/plugins/visualizations/charts/static/library/portlet.js
--- a/config/plugins/visualizations/charts/static/library/portlet.js
+++ b/config/plugins/visualizations/charts/static/library/portlet.js
@@ -45,6 +45,7 @@
// link functions
var self = this;
$.each(this.options.buttons, function(name, item) {
+ item.$el.prop('id', name);
self.$buttons.append(item.$el);
});
} else {
@@ -57,6 +58,7 @@
// link functions
var self = this;
$.each(this.options.operations, function(name, item) {
+ item.$el.prop('id', name);
self.$operations.append(item.$el);
});
}
@@ -96,13 +98,23 @@
},
// enable buttons
- enableButton: function(name) {
- this.$buttons.find('#' + String(name).toLowerCase()).prop('disabled', false);
+ enableButton: function(id) {
+ this.$buttons.find('#' + id).prop('disabled', false);
},
// disable buttons
- disableButton: function(name) {
- this.$buttons.find('#' + String(name).toLowerCase()).prop('disabled', true);
+ disableButton: function(id) {
+ this.$buttons.find('#' + id).prop('disabled', true);
+ },
+
+ // enable operation
+ hideOperation: function(id) {
+ this.$operations.find('#' + id).hide();
+ },
+
+ // disable operation
+ showOperation: function(id) {
+ this.$operations.find('#' + id).show();
},
// fill regular modal template
diff -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 -r 8deba81aad81fd565a7e33bad10bb8e741a6172b config/plugins/visualizations/charts/static/library/ui.js
--- a/config/plugins/visualizations/charts/static/library/ui.js
+++ b/config/plugins/visualizations/charts/static/library/ui.js
@@ -34,6 +34,7 @@
{
// options
optionsDefault: {
+ id : null,
label : '',
float : 'right',
cls : 'btn-default',
@@ -55,7 +56,7 @@
// element
template: function(options) {
- var str = '<button type="' + options.type + '" style="margin-right: 5px; float: ' + options.float + ';" type="button" class="btn ' + options.cls + '">';
+ var str = '<button id="' + options.id + '" type="' + options.type + '" style="margin-right: 5px; float: ' + options.float + ';" type="button" class="btn ' + options.cls + '">';
if (options.icon) {
str += '<i class="icon fa ' + options.icon + '"></i> ' ;
}
@@ -375,6 +376,7 @@
{
// options
optionsDefault: {
+ id : null,
label : '',
float : 'right',
cls : 'icon-btn',
@@ -403,7 +405,7 @@
// element
template: function(options) {
- var str = '<a style="margin-right: 5px; float: ' + options.float + ';" class="' + options.cls + '">';
+ var str = '<a id="' + options.id + '" style="margin-right: 5px; float: ' + options.float + ';" class="' + options.cls + '">';
if (options.icon) {
str += '<i class="icon fa ' + options.icon + '"></i>';
}
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
2 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/a4108edecdd5/
Changeset: a4108edecdd5
User: guerler
Date: 2014-01-16 06:42:41
Summary: Charts: Show chart creation form on startup, add pie chart
Affected #: 8 files
diff -r d2f73445ce7ada2f13947aa7c7c8506743d40d3f -r a4108edecdd5bfc9cc185866429bfa8297cab41e config/plugins/visualizations/charts/config/charts.xml
--- a/config/plugins/visualizations/charts/config/charts.xml
+++ b/config/plugins/visualizations/charts/config/charts.xml
@@ -1,15 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE visualization SYSTEM "../../visualization.dtd">
-<visualization name="charts">
+<visualization name="Charts"><data_sources><data_source><model_class>HistoryDatasetAssociation</model_class><test type="isinstance" test_attr="datatype" result_type="datatype">tabular.Tabular</test><to_param param_attr="id">dataset_id</to_param></data_source>
+ <data_source>
+ <model_class>Visualization</model_class>
+ <test test_attr="type">charts</test>
+ <to_param param_attr="id">visualization_id</to_param>
+ </data_source></data_sources><params><param type="dataset" var_name_in_template="hda" required="true">dataset_id</param>
+ <param type="visualization" var_name_in_template="visualization">visualization_id</param></params><template>charts.mako</template></visualization>
diff -r d2f73445ce7ada2f13947aa7c7c8506743d40d3f -r a4108edecdd5bfc9cc185866429bfa8297cab41e config/plugins/visualizations/charts/static/app.js
--- a/config/plugins/visualizations/charts/static/app.js
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -44,10 +44,13 @@
// create
this.config.$el.hide();
- this.create.$el.hide();
+ this.main.$el.hide();
// set elements
this.setElement(this.portlet.$el);
+
+ // reset create view
+ this.create.reset();
},
// execute command
diff -r d2f73445ce7ada2f13947aa7c7c8506743d40d3f -r a4108edecdd5bfc9cc185866429bfa8297cab41e config/plugins/visualizations/charts/static/charts/piechart.js
--- a/config/plugins/visualizations/charts/static/charts/piechart.js
+++ b/config/plugins/visualizations/charts/static/charts/piechart.js
@@ -14,23 +14,37 @@
// render
refresh : function(data)
{
- // add graph to screen
- var self = this;
- nv.addGraph(function() {
- self.chart_3d = nv.models.pieChart()
- .x(function(d) { return d.key })
- .y(function(d) { return d.y })
- .showLabels(true);
+ // loop through data groups
+ for (var key in data) {
+ // get group
+ var group = data[key];
+
+ // format chart data
+ var pie_data = [];
+ for (var key in group.values) {
+ var value = group.values[key];
+ pie_data.push ({
+ key : value.x,
+ y : value.y
+ });
+ }
+
+ // add graph to screen
+ var self = this;
+ nv.addGraph(function() {
+ self.chart_3d = nv.models.pieChart()
+ .donut(true)
+ .showLegend(false);
- d3.select(self.options.svg_id)
- .datum(data)
- .transition().duration(1200)
- .call(self.chart_3d);
+ d3.select(self.options.svg_id)
+ .datum(pie_data)
+ .call(self.chart_3d);
- nv.utils.windowResize(self.chart_3d.update);
-
- return self.chart_3d;
- });
+ nv.utils.windowResize(self.chart_3d.update);
+
+ return self.chart_3d;
+ });
+ }
}
});
diff -r d2f73445ce7ada2f13947aa7c7c8506743d40d3f -r a4108edecdd5bfc9cc185866429bfa8297cab41e config/plugins/visualizations/charts/static/create.js
--- a/config/plugins/visualizations/charts/static/create.js
+++ b/config/plugins/visualizations/charts/static/create.js
@@ -29,7 +29,7 @@
// main elements
this.message = new Ui.Message();
this.title = new Ui.Input({placeholder: 'Chart title'});
- this.dataset = new Ui.Input({value : app.options.dataset.id, disabled: true});
+ this.dataset = new Ui.Input({value : app.options.dataset.id, disabled: true, visible: false});
// configure dataset
this.groups = new Groups(this.app);
@@ -91,14 +91,14 @@
operations : {
'save' : new Ui.ButtonIcon({
icon : 'fa-save',
- tooltip : 'Save',
+ tooltip : 'Save Chart',
onclick : function() {
self._saveChart();
}
}),
'back' : new Ui.ButtonIcon({
- icon : 'fa-caret-left',
- tooltip : 'Return',
+ icon : 'fa-list',
+ tooltip : 'Show Charts',
onclick : function() {
self.$el.hide();
self.app.main.$el.show();
@@ -107,10 +107,9 @@
}
});
this.portlet.append(this.message.$el);
+ this.portlet.append(this.dataset.$el);
this.portlet.append((new Ui.Label({ label : 'Provide a chart title:'})).$el);
this.portlet.append(this.title.$el);
- this.portlet.append((new Ui.Label({ label : 'Select a dataset:'})).$el);
- this.portlet.append(this.dataset.$el);
this.portlet.append((new Ui.Label({ label : 'Select a chart type:'})).$el);
this.portlet.append(this.table.$el);
this.portlet.append(this.groups.$el);
@@ -132,7 +131,7 @@
reset: function() {
this.chart.reset();
this.chart.set('id', Utils.uuid());
- this.chart.set('dataset_id', app.options.dataset.id);
+ this.chart.set('dataset_id', this.app.options.dataset.id);
this.chart.set('type', 'bardiagram');
this.chart.set('title', 'Chart title');
},
diff -r d2f73445ce7ada2f13947aa7c7c8506743d40d3f -r a4108edecdd5bfc9cc185866429bfa8297cab41e config/plugins/visualizations/charts/static/groups.js
--- a/config/plugins/visualizations/charts/static/groups.js
+++ b/config/plugins/visualizations/charts/static/groups.js
@@ -14,7 +14,7 @@
// table
this.table = new Table({
- content : 'Add data sources to this table.',
+ content : 'Add data columns to this table.',
ondblclick : function(group_id) {
// get group
var group = self.app.chart.groups.get(group_id);
@@ -30,7 +30,7 @@
var self = this;
this.portlet = new Portlet({
icon : '',
- label : 'Configure data sources:',
+ label : 'Select data columns:',
height : 100,
operations : {
'new' : new Ui.ButtonIcon({
diff -r d2f73445ce7ada2f13947aa7c7c8506743d40d3f -r a4108edecdd5bfc9cc185866429bfa8297cab41e config/plugins/visualizations/charts/static/library/ui.js
--- a/config/plugins/visualizations/charts/static/library/ui.js
+++ b/config/plugins/visualizations/charts/static/library/ui.js
@@ -422,7 +422,8 @@
value : '',
type : 'text',
placeholder : '',
- disabled : false
+ disabled : false,
+ visible : true
},
// initialize
@@ -440,6 +441,11 @@
if (this.options.disabled) {
this.$el.prop('disabled', true);
}
+
+ // hide input field
+ if (!this.options.visible) {
+ this.$el.hide();
+ }
},
// value
diff -r d2f73445ce7ada2f13947aa7c7c8506743d40d3f -r a4108edecdd5bfc9cc185866429bfa8297cab41e config/plugins/visualizations/charts/static/models/types.js
--- a/config/plugins/visualizations/charts/static/models/types.js
+++ b/config/plugins/visualizations/charts/static/models/types.js
@@ -39,7 +39,7 @@
}
},
'piechart' : {
- title : 'Pie chart (under development)',
+ title : 'Pie chart',
data : {
y : {
title : 'Values for y-axis'
diff -r d2f73445ce7ada2f13947aa7c7c8506743d40d3f -r a4108edecdd5bfc9cc185866429bfa8297cab41e config/plugins/visualizations/charts/static/plugins/nv.d3.js
--- a/config/plugins/visualizations/charts/static/plugins/nv.d3.js
+++ b/config/plugins/visualizations/charts/static/plugins/nv.d3.js
@@ -2,5 +2,5 @@
n.values.map(function(e,n){return e.display={y:(t.y()(e,n)-i)/(1+i)},e}),n)})}var t=e.models.line(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o=e.interactiveGuideline(),u={top:30,right:30,bottom:50,left:60},a=e.utils.defaultColor(),f=null,l=null,c=!0,h=!0,p=!0,d=!1,v=!0,m=!0,g=!1,y=!0,b=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},w,E,S=t.id(),x={index:0,rescaleY:y},T=null,N="No Data Available.",C=function(e){return e.average},k=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),L=250,A=!1;n.orient("bottom").tickPadding(7),r.orient(d?"right":"left"),s.updateState(!1);var O=d3.scale.linear(),M={i:0,x:0},_=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=b(i.series.key,a,f,i,D);e.tooltip.show([o,u],l,null,null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+u.left,e.pos[1]+u.top],k.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){k.tooltipHide(e)}),k.on("tooltipHide",function(){v&&e.tooltip.cleanup()}),D.dispatch=k,D.lines=t,D.legend=i,D.xAxis=n,D.yAxis=r,D.interactiveLayer=o,d3.rebind(D,t,"defined","isArea","x","y","xScale","yScale","size","xDomain","yDomain","xRange","yRange","forceX","forceY","interactive","clipEdge","clipVoronoi","useVoronoi","id"),D.options=e.utils.optionsFunc.bind(D),D.margin=function(e){return arguments.length?(u.top=typeof e.top!="undefined"?e.top:u.top,u.right=typeof e.right!="undefined"?e.right:u.right,u.bottom=typeof e.bottom!="undefined"?e.bottom:u.bottom,u.left=typeof e.left!="undefined"?e.left:u.left,D):u},D.width=function(e){return arguments.length?(f=e,D):f},D.height=function(e){return arguments.length?(l=e,D):l},D.color=function(t){return arguments.length?(a=e.utils.getColor(t),i.color(a),D):a},D.rescaleY=function(e){return arguments.length?(y=e,D):y},D.showControls=function(e){return arguments.length?(m=e,D):m},D.useInteractiveGuideline=function(e){return arguments.length?(g=e,e===!0&&(D.interactive(!1),D.useVoronoi(!1)),D):g},D.showLegend=function(e){return arguments.length?(c=e,D):c},D.showXAxis=function(e){return arguments.length?(h=e,D):h},D.showYAxis=function(e){return arguments.length?(p=e,D):p},D.rightAlignYAxis=function(e){return arguments.length?(d=e,r.orient(e?"right":"left"),D):d},D.tooltips=function(e){return arguments.length?(v=e,D):v},D.tooltipContent=function(e){return arguments.length?(b=e,D):b},D.state=function(e){return arguments.length?(x=e,D):x},D.defaultState=function(e){return arguments.length?(T=e,D):T},D.noData=function(e){return arguments.length?(N=e,D):N},D.average=function(e){return arguments.length?(C=e,D):C},D.transitionDuration=function(e){return arguments.length?(L=e,D):L},D.noErrorCheck=function(e){return arguments.length?(A=e,D):A},D},e.models.discreteBar=function(){"use strict";function E(e){return e.each(function(e){var i=n-t.left-t.right,E=r-t.top-t.bottom,S=d3.select(this);e.forEach(function(e,t){e.values.forEach(function(e){e.series=t})});var T=p&&d?[]:e.map(function(e){return e.values.map(function(e,t){return{x:u(e,t),y:a(e,t),y0:e.y0}})});s.domain(p||d3.merge(T).map(function(e){return e.x})).rangeBands(v||[0,i],.1),o.domain(d||d3.extent(d3.merge(T).map(function(e){return e.y}).concat(f))),c?o.range(m||[E-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]):o.range(m||[E,0]),b=b||s,w=w||o.copy().range([o(0),o(0)]);var N=S.selectAll("g.nv-wrap.nv-discretebar").data([e]),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),k=C.append("g"),L=N.select("g");k.append("g").attr("class","nv-groups"),N.attr("transform","translate("+t.left+","+t.top+")");var A=N.select(".nv-groups").selectAll(".nv-group").data(function(e){return e},function(e){return e.key});A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),A.exit().transition().style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),A.attr("class",function(e,t){return"nv-group nv-series-"+t}).classed("hover",function(e){return e.hover}),A.transition().style("stroke-opacity",1).style("fill-opacity",.75);var O=A.selectAll("g.nv-bar").data(function(e){return e.values});O.exit().remove();var M=O.enter().append("g").attr("transform",function(e,t,n){return"translate("+(s(u(e,t))+s.rangeBand()*.05)+", "+o(0)+")"}).on("mouseover",function(t,n){d3.select(this).classed("hover",!0),g.elementMouseover({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(t.series+.5)/e.length,o(a(t,n))],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),g.elementMouseout({value:a(t,n),point:t,series:e[t.series],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("click",function(t,n){g.elementClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(t.series+.5)/e.length,o(a(t,n))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(t,n){g.elementDblClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(t.series+.5)/e.length,o(a(t,n))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()});M.append("rect").attr("height",0).attr("width",s.rangeBand()*.9/e.length),c?(M.append("text").attr("text-anchor","middle"),O.select("text").text(function(e,t){return h(a(e,t))}).transition().attr("x",s.rangeBand()*.9/2).attr("y",function(e,t){return a(e,t)<0?o(a(e,t))-o(0)+12:-4})):O.selectAll("text").remove(),O.attr("class",function(e,t){return a(e,t)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(e,t){return e.color||l(e,t)}).style("stroke",function(e,t){return e.color||l(e,t)}).select("rect").attr("class",y).transition().attr("width",s.rangeBand()*.9/e.length),O.transition().attr("transform",function(e,t){var n=s(u(e,t))+s.rangeBand()*.05,r=a(e,t)<0?o(0):o(0)-o(a(e,t))<1?o(0)-1:o(a(e,t));return"translate("+n+", "+r+")"}).select("rect").attr("height",function(e,t){return Math.max(Math.abs(o(a(e,t))-o(d&&d[0]||0))||1)}),b=s.copy(),w=o.copy()}),E}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.ordinal(),o=d3.scale.linear(),u=function(e){return e.x},a=function(e){return e.y},f=[0],l=e.utils.defaultColor(),c=!1,h=d3.format(",.2f"),p,d,v,m,g=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout"),y="discreteBar",b,w;return E.dispatch=g,E.options=e.utils.optionsFunc.bind(E),E.x=function(e){return arguments.length?(u=e,E):u},E.y=function(e){return arguments.length?(a=e,E):a},E.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,E):t},E.width=function(e){return arguments.length?(n=e,E):n},E.height=function(e){return arguments.length?(r=e,E):r},E.xScale=function(e){return arguments.length?(s=e,E):s},E.yScale=function(e){return arguments.length?(o=e,E):o},E.xDomain=function(e){return arguments.length?(p=e,E):p},E.yDomain=function(e){return arguments.length?(d=e,E):d},E.xRange=function(e){return arguments.length?(v=e,E):v},E.yRange=function(e){return arguments.length?(m=e,E):m},E.forceY=function(e){return arguments.length?(f=e,E):f},E.color=function(t){return arguments.length?(l=e.utils.getColor(t),E):l},E.id=function(e){return arguments.length?(i=e,E):i},E.showValues=function(e){return arguments.length?(c=e,E):c},E.valueFormat=function(e){return arguments.length?(h=e,E):h},E.rectClass=function(e){return arguments.length?(y=e,E):y},E},e.models.discreteBarChart=function(){"use strict";function w(e){return e.each(function(e){var u=d3.select(this),p=this,E=(s||parseInt(u.style("width"))||960)-i.left-i.right,S=(o||parseInt(u.style("height"))||400)-i.top-i.bottom;w.update=function(){g.beforeUpdate(),u.transition().duration(y).call(w)},w.container=this;if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var T=u.selectAll(".nv-noData").data([m]);return T.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),T.attr("x",i.left+E/2).attr("y",i.top+S/2).text(function(e){return e}),w}u.selectAll(".nv-noData").remove(),d=t.xScale(),v=t.yScale().clamp(!0);var N=u.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([e]),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),k=C.append("defs"),L=N.select("g");C.append("g").attr("class","nv-x nv-axis"),C.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),C.append("g").attr("class","nv-barsWrap"),L.attr("transform","translate("+i.left+","+i.top+")"),l&&L.select(".nv-y.nv-axis").attr("transform","translate("+E+",0)"),t.width(E).height(S);var A=L.select(".nv-barsWrap").datum(e.filter(function(e){return!e.disabled}));A.transition().call(t),k.append("clipPath").attr("id","nv-x-label-clip-"+t.id()).append("rect"),L.select("#nv-x-label-clip-"+t.id()+" rect").attr("width",d.rangeBand()*(c?2:1)).attr("height",16).attr("x",-d.rangeBand()/(c?1:2));if(a){n.scale(d).ticks(E/100).tickSize(-S,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+(v.range()[0]+(t.showValues()&&v.domain()[0]<0?16:0))+")"),L.select(".nv-x.nv-axis").transition().call(n);var O=L.select(".nv-x.nv-axis").selectAll("g");c&&O.selectAll("text").attr("transform",function(e,t,n){return"translate(0,"+(n%2==0?"5":"17")+")"})}f&&(r.scale(v).ticks(S/36).tickSize(-E,0),L.select(".nv-y.nv-axis").transition().call(r)),L.select(".nv-zeroLine line").attr("x1",0).attr("x2",E).attr("y1",v(0)).attr("y2",v(0)),g.on("tooltipShow",function(e){h&&b(e,p.parentNode)})}),w}var t=e.models.discreteBar(),n=e.models.axis(),r=e.models.axis(),i={top:15,right:10,bottom:50,left:60},s=null,o=null,u=e.utils.getColor(),a=!0,f=!0,l=!1,c=!1,h=!0,p=function(e,t,n,r,i){return"<h3>"+t+"</h3>"+"<p>"+n+"</p>"},d,v,m="No Data Available.",g=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate"),y=250;n.orient("bottom").highlightZero(!1).showMaxMin(!1).tickFormat(function(e){return e}),r.orient(l?"right":"left").tickFormat(d3.format(",.1f"));var b=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=p(i.series.key,a,f,i,w);e.tooltip.show([o,u],l,i.value<0?"n":"s",null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+i.left,e.pos[1]+i.top],g.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){g.tooltipHide(e)}),g.on("tooltipHide",function(){h&&e.tooltip.cleanup()}),w.dispatch=g,w.discretebar=t,w.xAxis=n,w.yAxis=r,d3.rebind(w,t,"x","y","xDomain","yDomain","xRange","yRange","forceX","forceY","id","showValues","valueFormat"),w.options=e.utils.optionsFunc.bind(w),w.margin=function(e){return arguments.length?(i.top=typeof e.top!="undefined"?e.top:i.top,i.right=typeof e.right!="undefined"?e.right:i.right,i.bottom=typeof e.bottom!="undefined"?e.bottom:i.bottom,i.left=typeof e.left!="undefined"?e.left:i.left,w):i},w.width=function(e){return arguments.length?(s=e,w):s},w.height=function(e){return arguments.length?(o=e,w):o},w.color=function(n){return arguments.length?(u=e.utils.getColor(n),t.color(u),w):u},w.showXAxis=function(e){return arguments.length?(a=e,w):a},w.showYAxis=function(e){return arguments.length?(f=e,w):f},w.rightAlignYAxis=function(e){return arguments.length?(l=e,r.orient(e?"right":"left"),w):l},w.staggerLabels=function(e){return arguments.length?(c=e,w):c},w.tooltips=function(e){return arguments.length?(h=e,w):h},w.tooltipContent=function(e){return arguments.length?(p=e,w):p},w.noData=function(e){return arguments.length?(m=e,w):m},w.transitionDuration=function(e){return arguments.length?(y=e,w):y},w},e.models.distribution=function(){"use strict";function l(e){return e.each(function(e){var a=n-(i==="x"?t.left+t.right:t.top+t.bottom),l=i=="x"?"y":"x",c=d3.select(this);f=f||u;var h=c.selectAll("g.nv-distribution").data([e]),p=h.enter().append("g").attr("class","nvd3 nv-distribution"),d=p.append("g"),v=h.select("g");h.attr("transform","translate("+t.left+","+t.top+")");var m=v.selectAll("g.nv-dist").data(function(e){return e},function(e){return e.key});m.enter().append("g"),m.attr("class",function(e,t){return"nv-dist nv-series-"+t}).style("stroke",function(e,t){return o(e,t)});var g=m.selectAll("line.nv-dist"+i).data(function(e){return e.values});g.enter().append("line").attr(i+"1",function(e,t){return f(s(e,t))}).attr(i+"2",function(e,t){return f(s(e,t))}),m.exit().selectAll("line.nv-dist"+i).transition().attr(i+"1",function(e,t){return u(s(e,t))}).attr(i+"2",function(e,t){return u(s(e,t))}).style("stroke-opacity",0).remove(),g.attr("class",function(e,t){return"nv-dist"+i+" nv-dist"+i+"-"+t}).attr(l+"1",0).attr(l+"2",r),g.transition().attr(i+"1",function(e,t){return u(s(e,t))}).attr(i+"2",function(e,t){return u(s(e,t))}),f=u.copy()}),l}var t={top:0,right:0,bottom:0,left:0},n=400,r=8,i="x",s=function(e){return e[i]},o=e.utils.defaultColor(),u=d3.scale.linear(),a,f;return l.options=e.utils.optionsFunc.bind(l),l.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,l):t},l.width=function(e){return arguments.length?(n=e,l):n},l.axis=function(e){return arguments.length?(i=e,l):i},l.size=function(e){return arguments.length?(r=e,l):r},l.getData=function(e){return arguments.length?(s=d3.functor(e),l):s},l.scale=function(e){return arguments.length?(u=e,l):u},l.color=function(t){return arguments.length?(o=e.utils.getColor(t),l):o},l},e.models.historicalBar=function(){"use strict";function w(E){return E.each(function(w){var E=n-t.left-t.right,S=r-t.top-t.bottom,T=d3.select(this);s.domain(d||d3.extent(w[0].values.map(u).concat(f))),c?s.range(m||[E*.5/w[0].values.length,E*(w[0].values.length-.5)/w[0].values.length]):s.range(m||[0,E]),o.domain(v||d3.extent(w[0].values.map(a).concat(l))).range(g||[S,0]),s.domain()[0]===s.domain()[1]&&(s.domain()[0]?s.domain([s.domain()[0]-s.domain()[0]*.01,s.domain()[1]+s.domain()[1]*.01]):s.domain([-1,1])),o.domain()[0]===o.domain()[1]&&(o.domain()[0]?o.domain([o.domain()[0]+o.domain()[0]*.01,o.domain()[1]-o.domain()[1]*.01]):o.domain([-1,1]));var N=T.selectAll("g.nv-wrap.nv-historicalBar-"+i).data([w[0].values]),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+i),k=C.append("defs"),L=C.append("g"),A=N.select("g");L.append("g").attr("class","nv-bars"),N.attr("transform","translate("+t.left+","+t.top+")"),T.on("click",function(e,t){y.chartClick({data:e,index:t,pos:d3.event,id:i})}),k.append("clipPath").attr("id","nv-chart-clip-path-"+i).append("rect"),N.select("#nv-chart-clip-path-"+i+" rect").attr("width",E).attr("height",S),A.attr("clip-path",h?"url(#nv-chart-clip-path-"+i+")":"");var O=N.select(".nv-bars").selectAll(".nv-bar").data(function(e){return e},function(e,t){return u(e,t)});O.exit().remove();var M=O.enter().append("rect").attr("x",0).attr("y",function(t,n){return e.utils.NaNtoZero(o(Math.max(0,a(t,n))))}).attr("height",function(t,n){return e.utils.NaNtoZero(Math.abs(o(a(t,n))-o(0)))}).attr("transform",function(e,t){return"translate("+(s(u(e,t))-E/w[0].values.length*.45)+",0)"}).on("mouseover",function(e,t){if(!b)return;d3.select(this).classed("hover",!0),y.elementMouseover({point:e,series:w[0],pos:[s(u(e,t)),o(a(e,t))],pointIndex:t,seriesIndex:0,e:d3.event})}).on("mouseout",function(e,t){if(!b)return;d3.select(this).classed("hover",!1),y.elementMouseout({point:e,series:w[0],pointIndex:t,seriesIndex:0,e:d3.event})}).on("click",function(e,t){if(!b)return;y.elementClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))],e:d3.event,id:i}),d3.event.stopPropagation()}).on("dblclick",function(e,t){if(!b)return;y.elementDblClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))],e:d3.event,id:i}),d3.event.stopPropagation()});O.attr("fill",function(e,t){return p(e,t)}).attr("class",function(e,t,n){return(a(e,t)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+n+"-"+t}).transition().attr("transform",function(e,t){return"translate("+(s(u(e,t))-E/w[0].values.length*.45)+",0)"}).attr("width",E/w[0].values.length*.9),O.transition().attr("y",function(t,n){var r=a(t,n)<0?o(0):o(0)-o(a(t,n))<1?o(0)-1:o(a(t,n));return e.utils.NaNtoZero(r)}).attr("height",function(t,n){return e.utils.NaNtoZero(Math.max(Math.abs(o(a(t,n))-o(0)),1))})}),w}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.linear(),o=d3.scale.linear(),u=function(e){return e.x},a=function(e){return e.y},f=[],l=[0],c=!1,h=!0,p=e.utils.defaultColor(),d,v,m,g,y=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout"),b=!0;return w.highlightPoint=function(e,t){d3.select(".nv-historicalBar-"+i).select(".nv-bars .nv-bar-0-"+e).classed("hover",t)},w.clearHighlights=function(){d3.select(".nv-historicalBar-"+i).select(".nv-bars .nv-bar.hover").classed("hover",!1)},w.dispatch=y,w.options=e.utils.optionsFunc.bind(w),w.x=function(e){return arguments.length?(u=e,w):u},w.y=function(e){return arguments.length?(a=e,w):a},w.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,w):t},w.width=function(e){return arguments.length?(n=e,w):n},w.height=function(e){return arguments.length?(r=e,w):r},w.xScale=function(e){return arguments.length?(s=e,w):s},w.yScale=function(e){return arguments.length?(o=e,w):o},w.xDomain=function(e){return arguments.length?(d=e,w):d},w.yDomain=function(e){return arguments.length?(v=e,w):v},w.xRange=function(e){return arguments.length?(m=e,w):m},w.yRange=function(e){return arguments.length?(g=e,w):g},w.forceX=function(e){return arguments.length?(f=e,w):f},w.forceY=function(e){return arguments.length?(l=e,w):l},w.padData=function(e){return arguments.length?(c=e,w):c},w.clipEdge=function(e){return arguments.length?(h=e,w):h},w.color=function(t){return arguments.length?(p=e.utils.getColor(t),w):p},w.id=function(e){return arguments.length?(i=e,w):i},w.interactive=function(e){return arguments.length?(b=!1,w):b},w},e.models.historicalBarChart=function(){"use strict";function x(e){return e.each(function(d){var T=d3.select(this),N=this,C=(u||parseInt(T.style("width"))||960)-s.left-s.right,k=(a||parseInt(T.style("height"))||400)-s.top-s.bottom;x.update=function(){T.transition().duration(E).call(x)},x.container=this,g.disabled=d.map(function(e){return!!e.disabled});if(!y){var L;y={};for(L in g)g[L]instanceof Array?y[L]=g[L].slice(0):y[L]=g[L]}if(!d||!d.length||!d.filter(function(e){return e.values.length}).length){var A=T.selectAll(".nv-noData").data([b]);return A.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),A.attr("x",s.left+C/2).attr("y",s.top+k/2).text(function(e){return e}),x}T.selectAll(".nv-noData").remove(),v=t.xScale(),m=t.yScale();var O=T.selectAll("g.nv-wrap.nv-historicalBarChart").data([d]),M=O.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),_=O.select("g");M.append("g").attr("class","nv-x nv-axis"),M.append("g").attr("class","nv-y nv-axis"),M.append("g").attr("class","nv-barsWrap"),M.append("g").attr("class","nv-legendWrap"),f&&(i.width(C),_.select(".nv-legendWrap").datum(d).call(i),s.top!=i.height()&&(s.top=i.height(),k=(a||parseInt(T.style("height"))||400)-s.top-s.bottom),O.select(".nv-legendWrap").attr("transform","translate(0,"+ -s.top+")")),O.attr("transform","translate("+s.left+","+s.top+")"),h&&_.select(".nv-y.nv-axis").attr("transform","translate("+C+",0)"),t.width(C).height(k).color(d.map(function(e,t){return e.color||o(e,t)}).filter(function(e,t){return!d[t].disabled}));var D=_.select(".nv-barsWrap").datum(d.filter(function(e){return!e.disabled}));D.transition().call(t),l&&(n.scale(v).tickSize(-k,0),_.select(".nv-x.nv-axis").attr("transform","translate(0,"+m.range()[0]+")"),_.select(".nv-x.nv-axis").transition().call(n)),c&&(r.scale(m).ticks(k/36).tickSize(-C,0),_.select(".nv-y.nv-axis").transition().call(r)),i.dispatch.on("legendClick",function(t,n){t.disabled=!t.disabled,d.filter(function(e){return!e.disabled}).length||d.map(function(e){return e.disabled=!1,O.selectAll(".nv-series").classed("disabled",!1),e}),g.disabled=d.map(function(e){return!!e.disabled}),w.stateChange(g),e.transition().call(x)}),i.dispatch.on("legendDblclick",function(e){d.forEach(function(e){e.disabled=!0}),e.disabled=!1,g.disabled=d.map(function(e){return!!e.disabled}),w.stateChange(g),x.update()}),w.on("tooltipShow",function(e){p&&S(e,N.parentNode)}),w.on("changeState",function(e){typeof e.disabled!="undefined"&&(d.forEach(function(t,n){t.disabled=e.disabled[n]}),g.disabled=e.disabled),x.update()})}),x}var t=e.models.historicalBar(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s={top:30,right:90,bottom:50,left:90},o=e.utils.defaultColor(),u=null,a=null,f=!1,l=!0,c=!0,h=!1,p=!0,d=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},v,m,g={},y=null,b="No Data Available.",w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),E=250;n.orient("bottom").tickPadding(7),r.orient(h?"right":"left");var S=function(i,s){if(s){var o=d3.select(s).select("svg"),u=o.node()?o.attr("viewBox"):null;if(u){u=u.split(" ");var a=parseInt(o.style("width"))/u[2];i.pos[0]=i.pos[0]*a,i.pos[1]=i.pos[1]*a}}var f=i.pos[0]+(s.offsetLeft||0),l=i.pos[1]+(s.offsetTop||0),c=n.tickFormat()(t.x()(i.point,i.pointIndex)),h=r.tickFormat()(t.y()(i.point,i.pointIndex)),p=d(i.series.key,c,h,i,x);e.tooltip.show([f,l],p,null,null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+s.left,e.pos[1]+s.top],w.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){w.tooltipHide(e)}),w.on("tooltipHide",function(){p&&e.tooltip.cleanup()}),x.dispatch=w,x.bars=t,x.legend=i,x.xAxis=n,x.yAxis=r,d3.rebind(x,t,"defined","isArea","x","y","size","xScale","yScale","xDomain","yDomain","xRange","yRange","forceX","forceY","interactive","clipEdge","clipVoronoi","id","interpolate","highlightPoint","clearHighlights","interactive"),x.options=e.utils.optionsFunc.bind(x),x.margin=function(e){return arguments.length?(s.top=typeof e.top!="undefined"?e.top:s.top,s.right=typeof e.right!="undefined"?e.right:s.right,s.bottom=typeof e.bottom!="undefined"?e.bottom:s.bottom,s.left=typeof e.left!="undefined"?e.left:s.left,x):s},x.width=function(e){return arguments.length?(u=e,x):u},x.height=function(e){return arguments.length?(a=e,x):a},x.color=function(t){return arguments.length?(o=e.utils.getColor(t),i.color(o),x):o},x.showLegend=function(e){return arguments.length?(f=e,x):f},x.showXAxis=function(e){return arguments.length?(l=e,x):l},x.showYAxis=function(e){return arguments.length?(c=e,x):c},x.rightAlignYAxis=function(e){return arguments.length?(h=e,r.orient(e?"right":"left"),x):h},x.tooltips=function(e){return arguments.length?(p=e,x):p},x.tooltipContent=function(e){return arguments.length?(d=e,x):d},x.state=function(e){return arguments.length?(g=e,x):g},x.defaultState=function(e){return arguments.length?(y=e,x):y},x.noData=function(e){return arguments.length?(b=e,x):b},x.transitionDuration=function(e){return arguments.length?(E=e,x):E},x},e.models.indentedTree=function(){"use strict";function g(e){return e.each(function(e){function k(e,t,n){d3.event.stopPropagation();if(d3.event.shiftKey&&!n)return d3.event.shiftKey=!1,e.values&&e.values.forEach(function(e){(e.values||e._values)&&k(e,0,!0)}),!0;if(!O(e))return!0;e.values?(e._values=e.values,e.values=null):(e.values=e._values,e._values=null),g.update()}function L(e){return e._values&&e._values.length?h:e.values&&e.values.length?p:""}function A(e){return e._values&&e._values.length}function O(e){var t=e.values||e._values;return t&&t.length}var t=1,n=d3.select(this),i=d3.layout.tree().children(function(e){return e.values}).size([r,f]);g.update=function(){n.transition().duration(600).call(g)},e[0]||(e[0]={key:a});var s=i.nodes(e[0]),y=d3.select(this).selectAll("div").data([[s]]),b=y.enter().append("div").attr("class","nvd3 nv-wrap nv-indentedtree"),w=b.append("table"),E=y.select("table").attr("width","100%").attr("class",c);if(o){var S=w.append("thead"),x=S.append("tr");l.forEach(function(e){x.append("th").attr("width",e.width?e.width:"10%").style("text-align",e.type=="numeric"?"right":"left").append("span").text(e.label)})}var T=E.selectAll("tbody").data(function(e){return e});T.enter().append("tbody"),t=d3.max(s,function(e){return e.depth}),i.size([r,t*f]);var N=T.selectAll("tr").data(function(e){return e.filter(function(e){return u&&!e.children?u(e):!0})},function(e,t){return e.id||e.id||++m});N.exit().remove(),N.select("img.nv-treeicon").attr("src",L).classed("folded",A);var C=N.enter().append("tr");l.forEach(function(e,t){var n=C.append("td").style("padding-left",function(e){return(t?0:e.depth*f+12+(L(e)?0:16))+"px"},"important").style("text-align",e.type=="numeric"?"right":"left");t==0&&n.append("img").classed("nv-treeicon",!0).classed("nv-folded",A).attr("src",L).style("width","14px").style("height","14px").style("padding","0 1px").style("display",function(e){return L(e)?"inline-block":"none"}).on("click",k),n.each(function(n){!t&&v(n)?d3.select(this).append("a").attr("href",v).attr("class",d3.functor(e.classes)).append("span"):d3.select(this).append("span"),d3.select(this).select("span").attr("class",d3.functor(e.classes)).text(function(t){return e.format?e.format(t):t[e.key]||"-"})}),e.showCount&&(n.append("span").attr("class","nv-childrenCount"),N.selectAll("span.nv-childrenCount").text(function(e){return e.values&&e.values.length||e._values&&e._values.length?"("+(e.values&&e.values.filter(function(e){return u?u(e):!0}).length||e._values&&e._values.filter(function(e){return u?u(e):!0}).length||0)+")":""}))}),N.order().on("click",function(e){d.elementClick({row:this,data:e,pos:[e.x,e.y]})}).on("dblclick",function(e){d.elementDblclick({row:this,data:e,pos:[e.x,e.y]})}).on("mouseover",function(e){d.elementMouseover({row:this,data:e,pos:[e.x,e.y]})}).on("mouseout",function(e){d.elementMouseout({row:this,data:e,pos:[e.x,e.y]})})}),g}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=e.utils.defaultColor(),s=Math.floor(Math.random()*1e4),o=!0,u=!1,a="No Data Available.",f=20,l=[{key:"key",label:"Name",type:"text"}],c=null,h="images/grey-plus.png",p="images/grey-minus.png",d=d3.dispatch("elementClick","elementDblclick","elementMouseover","elementMouseout"),v=function(e){return e.url},m=0;return g.options=e.utils.optionsFunc.bind(g),g.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,g):t},g.width=function(e){return arguments.length?(n=e,g):n},g.height=function(e){return arguments.length?(r=e,g):r},g.color=function(t){return arguments.length?(i=e.utils.getColor(t),scatter.color(i),g):i},g.id=function(e){return arguments.length?(s=e,g):s},g.header=function(e){return arguments.length?(o=e,g):o},g.noData=function(e){return arguments.length?(a=e,g):a},g.filterZero=function(e){return arguments.length?(u=e,g):u},g.columns=function(e){return arguments.length?(l=e,g):l},g.tableClass=function(e){return arguments.length?(c=e,g):c},g.iconOpen=function(e){return arguments.length?(h=e,g):h},g.iconClose=function(e){return arguments.length?(p=e,g):p},g.getUrl=function(e){return arguments.length?(v=e,g):v},g},e.models.legend=function(){"use strict";function c(h){return h.each(function(c){var h=n-t.left-t.right,p=d3.select(this),d=p.selectAll("g.nv-legend").data([c]),v=d.enter().append("g").attr("class","nvd3 nv-legend").append("g"),m=d.select("g");d.attr("transform","translate("+t.left+","+t.top+")");var g=m.selectAll(".nv-series").data(function(e){return e}),y=g.enter().append("g").attr("class","nv-series").on("mouseover",function(e,t){l.legendMouseover(e,t)}).on("mouseout",function(e,t){l.legendMouseout(e,t)}).on("click",function(e,t){l.legendClick(e,t),a&&(f?(c.forEach(function(e){e.disabled=!0}),e.disabled=!1):(e.disabled=!e.disabled,c.every(function(e){return e.disabled})&&c.forEach(function(e){e.disabled=!1})),l.stateChange({disabled:c.map(function(e){return!!e.disabled})}))}).on("dblclick",function(e,t){l.legendDblclick(e,t),a&&(c.forEach(function(e){e.disabled=!0}),e.disabled=!1,l.stateChange({disabled:c.map(function(e){return!!e.disabled})}))});y.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),y.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8"),g.classed("disabled",function(e){return e.disabled}),g.exit().remove(),g.select("circle").style("fill",function(e,t){return e.color||s(e,t)}).style("stroke",function(e,t){return e.color||s(e,t)}),g.select("text").text(i);if(o){var b=[];g.each(function(t,n){var r=d3.select(this).select("text"),i;try{i=r.getComputedTextLength();if(i<=0)throw Error()}catch(s){i=e.utils.calcApproxTextWidth(r)}b.push(i+28)});var w=0,E=0,S=[];while(E<h&&w<b.length)S[w]=b[w],E+=b[w++];w===0&&(w=1);while(E>h&&w>1){S=[],w--;for(var x=0;x<b.length;x++)b[x]>(S[x%w]||0)&&(S[x%w]=b[x]);E=S.reduce(function(e,t,n,r){return e+t})}var T=[];for(var N=0,C=0;N<w;N++)T[N]=C,C+=S[N];g.attr("transform",function(e,t){return"translate("+T[t%w]+","+(5+Math.floor(t/w)*20)+")"}),u?m.attr("transform","translate("+(n-t.right-E)+","+t.top+")"):m.attr("transform","translate(0,"+t.top+")"),r=t.top+t.bottom+Math.ceil(b.length/w)*20}else{var k=5,L=5,A=0,O;g.attr("transform",function(e,r){var i=d3.select(this).select("text").node().getComputedTextLength()+28;return O=L,n<t.left+t.right+O+i&&(L=O=5,k+=20),L+=i,L>A&&(A=L),"translate("+O+","+k+")"}),m.attr("transform","translate("+(n-t.right-A)+","+t.top+")"),r=t.top+t.bottom+k+15}}),c}var t={top:5,right:0,bottom:5,left:0},n=400,r=20,i=function(e){return e.key},s=e.utils.defaultColor(),o=!0,u=!0,a=!0,f=!1,l=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange");return c.dispatch=l,c.options=e.utils.optionsFunc.bind(c),c.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,c):t},c.width=function(e){return arguments.length?(n=e,c):n},c.height=function(e){return arguments.length?(r=e,c):r},c.key=function(e){return arguments.length?(i=e,c):i},c.color=function(t){return arguments.length?(s=e.utils.getColor(t),c):s},c.align=function(e){return arguments.length?(o=e,c):o},c.rightAlign=function(e){return arguments.length?(u=e,c):u},c.updateState=function(e){return arguments.length?(a=e,c):a},c.radioButtonMode=function(e){return arguments.length?(f=e,c):f},c},e.models.line=function(){"use strict";function m(g){return g.each(function(m){var g=r-n.left-n.right,b=i-n.top-n.bottom,w=d3.select(this);c=t.xScale(),h=t.yScale(),d=d||c,v=v||h;var E=w.selectAll("g.nv-wrap.nv-line").data([m]),S=E.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),T=S.append("defs"),N=S.append("g"),C=E.select("g");N.append("g").attr("class","nv-groups"),N.append("g").attr("class","nv-scatterWrap"),E.attr("transform","translate("+n.left+","+n.top+")"),t.width(g).height(b);var k=E.select(".nv-scatterWrap");k.transition().call(t),T.append("clipPath").attr("id","nv-edge-clip-"+t.id()).append("rect"),E.select("#nv-edge-clip-"+t.id()+" rect").attr("width",g).attr("height",b),C.attr("clip-path",l?"url(#nv-edge-clip-"+t.id()+")":""),k.attr("clip-path",l?"url(#nv-edge-clip-"+t.id()+")":"");var L=E.select(".nv-groups").selectAll(".nv-group").data(function(e){return e},function(e){return e.key});L.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),L.exit().remove(),L.attr("class",function(e,t){return"nv-group nv-series-"+t}).classed("hover",function(e){return e.hover}).style("fill",function(e,t){return s(e,t)}).style("stroke",function(e,t){return s(e,t)}),L.transition().style("stroke-opacity",1).style("fill-opacity",.5);var A=L.selectAll("path.nv-area").data(function(e){return f(e)?[e]:[]});A.enter().append("path").attr("class","nv-area").attr("d",function(t){return d3.svg.area().interpolate(p).defined(a).x(function(t,n){return e.
utils.NaNtoZero(d(o(t,n)))}).y0(function(t,n){return e.utils.NaNtoZero(v(u(t,n)))}).y1(function(e,t){return v(h.domain()[0]<=0?h.domain()[1]>=0?0:h.domain()[1]:h.domain()[0])}).apply(this,[t.values])}),L.exit().selectAll("path.nv-area").remove(),A.transition().attr("d",function(t){return d3.svg.area().interpolate(p).defined(a).x(function(t,n){return e.utils.NaNtoZero(c(o(t,n)))}).y0(function(t,n){return e.utils.NaNtoZero(h(u(t,n)))}).y1(function(e,t){return h(h.domain()[0]<=0?h.domain()[1]>=0?0:h.domain()[1]:h.domain()[0])}).apply(this,[t.values])});var O=L.selectAll("path.nv-line").data(function(e){return[e.values]});O.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(p).defined(a).x(function(t,n){return e.utils.NaNtoZero(d(o(t,n)))}).y(function(t,n){return e.utils.NaNtoZero(v(u(t,n)))})),O.transition().attr("d",d3.svg.line().interpolate(p).defined(a).x(function(t,n){return e.utils.NaNtoZero(c(o(t,n)))}).y(function(t,n){return e.utils.NaNtoZero(h(u(t,n)))})),d=c.copy(),v=h.copy()}),m}var t=e.models.scatter(),n={top:0,right:0,bottom:0,left:0},r=960,i=500,s=e.utils.defaultColor(),o=function(e){return e.x},u=function(e){return e.y},a=function(e,t){return!isNaN(u(e,t))&&u(e,t)!==null},f=function(e){return e.area},l=!1,c,h,p="linear";t.size(16).sizeDomain([16,256]);var d,v;return m.dispatch=t.dispatch,m.scatter=t,d3.rebind(m,t,"id","interactive","size","xScale","yScale","zScale","xDomain","yDomain","xRange","yRange","sizeDomain","forceX","forceY","forceSize","clipVoronoi","useVoronoi","clipRadius","padData","highlightPoint","clearHighlights"),m.options=e.utils.optionsFunc.bind(m),m.margin=function(e){return arguments.length?(n.top=typeof e.top!="undefined"?e.top:n.top,n.right=typeof e.right!="undefined"?e.right:n.right,n.bottom=typeof e.bottom!="undefined"?e.bottom:n.bottom,n.left=typeof e.left!="undefined"?e.left:n.left,m):n},m.width=function(e){return arguments.length?(r=e,m):r},m.height=function(e){return arguments.length?(i=e,m):i},m.x=function(e){return arguments.length?(o=e,t.x(e),m):o},m.y=function(e){return arguments.length?(u=e,t.y(e),m):u},m.clipEdge=function(e){return arguments.length?(l=e,m):l},m.color=function(n){return arguments.length?(s=e.utils.getColor(n),t.color(s),m):s},m.interpolate=function(e){return arguments.length?(p=e,m):p},m.defined=function(e){return arguments.length?(a=e,m):a},m.isArea=function(e){return arguments.length?(f=d3.functor(e),m):f},m},e.models.lineChart=function(){"use strict";function N(m){return m.each(function(m){var C=d3.select(this),k=this,L=(a||parseInt(C.style("width"))||960)-o.left-o.right,A=(f||parseInt(C.style("height"))||400)-o.top-o.bottom;N.update=function(){C.transition().duration(x).call(N)},N.container=this,b.disabled=m.map(function(e){return!!e.disabled});if(!w){var O;w={};for(O in b)b[O]instanceof Array?w[O]=b[O].slice(0):w[O]=b[O]}if(!m||!m.length||!m.filter(function(e){return e.values.length}).length){var M=C.selectAll(".nv-noData").data([E]);return M.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),M.attr("x",o.left+L/2).attr("y",o.top+A/2).text(function(e){return e}),N}C.selectAll(".nv-noData").remove(),g=t.xScale(),y=t.yScale();var _=C.selectAll("g.nv-wrap.nv-lineChart").data([m]),D=_.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),P=_.select("g");D.append("rect").style("opacity",0),D.append("g").attr("class","nv-x nv-axis"),D.append("g").attr("class","nv-y nv-axis"),D.append("g").attr("class","nv-linesWrap"),D.append("g").attr("class","nv-legendWrap"),D.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",L).attr("height",A>0?A:0),l&&(i.width(L),P.select(".nv-legendWrap").datum(m).call(i),o.top!=i.height()&&(o.top=i.height(),A=(f||parseInt(C.style("height"))||400)-o.top-o.bottom),_.select(".nv-legendWrap").attr("transform","translate(0,"+ -o.top+")")),_.attr("transform","translate("+o.left+","+o.top+")"),p&&P.select(".nv-y.nv-axis").attr("transform","translate("+L+",0)"),d&&(s.width(L).height(A).margin({left:o.left,top:o.top}).svgContainer(C).xScale(g),_.select(".nv-interactive").call(s)),t.width(L).height(A).color(m.map(function(e,t){return e.color||u(e,t)}).filter(function(e,t){return!m[t].disabled}));var H=P.select(".nv-linesWrap").datum(m.filter(function(e){return!e.disabled}));H.transition().call(t),c&&(n.scale(g).ticks(L/100).tickSize(-A,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+y.range()[0]+")"),P.select(".nv-x.nv-axis").transition().call(n)),h&&(r.scale(y).ticks(A/36).tickSize(-L,0),P.select(".nv-y.nv-axis").transition().call(r)),i.dispatch.on("stateChange",function(e){b=e,S.stateChange(b),N.update()}),s.dispatch.on("elementMousemove",function(i){t.clearHighlights();var a,f,l,c=[];m.filter(function(e,t){return e.seriesIndex=t,!e.disabled}).forEach(function(n,r){f=e.interactiveBisect(n.values,i.pointXValue,N.x()),t.highlightPoint(r,f,!0);var s=n.values[f];if(typeof s=="undefined")return;typeof a=="undefined"&&(a=s),typeof l=="undefined"&&(l=N.xScale()(N.x()(s,f))),c.push({key:n.key,value:N.y()(s,f),color:u(n,n.seriesIndex)})});if(c.length>2){var h=N.yScale().invert(i.mouseY),p=Math.abs(N.yScale().domain()[0]-N.yScale().domain()[1]),d=.03*p,g=e.nearestValueIndex(c.map(function(e){return e.value}),h,d);g!==null&&(c[g].highlight=!0)}var y=n.tickFormat()(N.x()(a,f));s.tooltip.position({left:l+o.left,top:i.mouseY+o.top}).chartContainer(k.parentNode).enabled(v).valueFormatter(function(e,t){return r.tickFormat()(e)}).data({value:y,series:c})(),s.renderGuideLine(l)}),s.dispatch.on("elementMouseout",function(e){S.tooltipHide(),t.clearHighlights()}),S.on("tooltipShow",function(e){v&&T(e,k.parentNode)}),S.on("changeState",function(e){typeof e.disabled!="undefined"&&m.length===e.disabled.length&&(m.forEach(function(t,n){t.disabled=e.disabled[n]}),b.disabled=e.disabled),N.update()})}),N}var t=e.models.line(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.interactiveGuideline(),o={top:30,right:20,bottom:50,left:60},u=e.utils.defaultColor(),a=null,f=null,l=!0,c=!0,h=!0,p=!1,d=!1,v=!0,m=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},g,y,b={},w=null,E="No Data Available.",S=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),x=250;n.orient("bottom").tickPadding(7),r.orient(p?"right":"left");var T=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=m(i.series.key,a,f,i,N);e.tooltip.show([o,u],l,null,null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+o.left,e.pos[1]+o.top],S.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),S.on("tooltipHide",function(){v&&e.tooltip.cleanup()}),N.dispatch=S,N.lines=t,N.legend=i,N.xAxis=n,N.yAxis=r,N.interactiveLayer=s,d3.rebind(N,t,"defined","isArea","x","y","size","xScale","yScale","xDomain","yDomain","xRange","yRange","forceX","forceY","interactive","clipEdge","clipVoronoi","useVoronoi","id","interpolate"),N.options=e.utils.optionsFunc.bind(N),N.margin=function(e){return arguments.length?(o.top=typeof e.top!="undefined"?e.top:o.top,o.right=typeof e.right!="undefined"?e.right:o.right,o.bottom=typeof e.bottom!="undefined"?e.bottom:o.bottom,o.left=typeof e.left!="undefined"?e.left:o.left,N):o},N.width=function(e){return arguments.length?(a=e,N):a},N.height=function(e){return arguments.length?(f=e,N):f},N.color=function(t){return arguments.length?(u=e.utils.getColor(t),i.color(u),N):u},N.showLegend=function(e){return arguments.length?(l=e,N):l},N.showXAxis=function(e){return arguments.length?(c=e,N):c},N.showYAxis=function(e){return arguments.length?(h=e,N):h},N.rightAlignYAxis=function(e){return arguments.length?(p=e,r.orient(e?"right":"left"),N):p},N.useInteractiveGuideline=function(e){return arguments.length?(d=e,e===!0&&(N.interactive(!1),N.useVoronoi(!1)),N):d},N.tooltips=function(e){return arguments.length?(v=e,N):v},N.tooltipContent=function(e){return arguments.length?(m=e,N):m},N.state=function(e){return arguments.length?(b=e,N):b},N.defaultState=function(e){return arguments.length?(w=e,N):w},N.noData=function(e){return arguments.length?(E=e,N):E},N.transitionDuration=function(e){return arguments.length?(x=e,N):x},N},e.models.linePlusBarChart=function(){"use strict";function T(e){return e.each(function(e){var l=d3.select(this),c=this,v=(a||parseInt(l.style("width"))||960)-u.left-u.right,N=(f||parseInt(l.style("height"))||400)-u.top-u.bottom;T.update=function(){l.transition().call(T)},b.disabled=e.map(function(e){return!!e.disabled});if(!w){var C;w={};for(C in b)b[C]instanceof Array?w[C]=b[C].slice(0):w[C]=b[C]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var k=l.selectAll(".nv-noData").data([E]);return k.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),k.attr("x",u.left+v/2).attr("y",u.top+N/2).text(function(e){return e}),T}l.selectAll(".nv-noData").remove();var L=e.filter(function(e){return!e.disabled&&e.bar}),A=e.filter(function(e){return!e.bar});m=A.filter(function(e){return!e.disabled}).length&&A.filter(function(e){return!e.disabled})[0].values.length?t.xScale():n.xScale(),g=n.yScale(),y=t.yScale();var O=d3.select(this).selectAll("g.nv-wrap.nv-linePlusBar").data([e]),M=O.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),_=O.select("g");M.append("g").attr("class","nv-x nv-axis"),M.append("g").attr("class","nv-y1 nv-axis"),M.append("g").attr("class","nv-y2 nv-axis"),M.append("g").attr("class","nv-barsWrap"),M.append("g").attr("class","nv-linesWrap"),M.append("g").attr("class","nv-legendWrap"),p&&(o.width(v/2),_.select(".nv-legendWrap").datum(e.map(function(e){return e.originalKey=e.originalKey===undefined?e.key:e.originalKey,e.key=e.originalKey+(e.bar?" (left axis)":" (right axis)"),e})).call(o),u.top!=o.height()&&(u.top=o.height(),N=(f||parseInt(l.style("height"))||400)-u.top-u.bottom),_.select(".nv-legendWrap").attr("transform","translate("+v/2+","+ -u.top+")")),O.attr("transform","translate("+u.left+","+u.top+")"),t.width(v).height(N).color(e.map(function(e,t){return e.color||h(e,t)}).filter(function(t,n){return!e[n].disabled&&!e[n].bar})),n.width(v).height(N).color(e.map(function(e,t){return e.color||h(e,t)}).filter(function(t,n){return!e[n].disabled&&e[n].bar}));var D=_.select(".nv-barsWrap").datum(L.length?L:[{values:[]}]),P=_.select(".nv-linesWrap").datum(A[0]&&!A[0].disabled?A:[{values:[]}]);d3.transition(D).call(n),d3.transition(P).call(t),r.scale(m).ticks(v/100).tickSize(-N,0),_.select(".nv-x.nv-axis").attr("transform","translate(0,"+g.range()[0]+")"),d3.transition(_.select(".nv-x.nv-axis")).call(r),i.scale(g).ticks(N/36).tickSize(-v,0),d3.transition(_.select(".nv-y1.nv-axis")).style("opacity",L.length?1:0).call(i),s.scale(y).ticks(N/36).tickSize(L.length?0:-v,0),_.select(".nv-y2.nv-axis").style("opacity",A.length?1:0).attr("transform","translate("+v+",0)"),d3.transition(_.select(".nv-y2.nv-axis")).call(s),o.dispatch.on("stateChange",function(e){b=e,S.stateChange(b),T.update()}),S.on("tooltipShow",function(e){d&&x(e,c.parentNode)}),S.on("changeState",function(t){typeof t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),b.disabled=t.disabled),T.update()})}),T}var t=e.models.line(),n=e.models.historicalBar(),r=e.models.axis(),i=e.models.axis(),s=e.models.axis(),o=e.models.legend(),u={top:30,right:60,bottom:50,left:60},a=null,f=null,l=function(e){return e.x},c=function(e){return e.y},h=e.utils.defaultColor(),p=!0,d=!0,v=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},m,g,y,b={},w=null,E="No Data Available.",S=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState");n.padData(!0),t.clipEdge(!1).padData(!0),r.orient("bottom").tickPadding(7).highlightZero(!1),i.orient("left"),s.orient("right");var x=function(n,o){var u=n.pos[0]+(o.offsetLeft||0),a=n.pos[1]+(o.offsetTop||0),f=r.tickFormat()(t.x()(n.point,n.pointIndex)),l=(n.series.bar?i:s).tickFormat()(t.y()(n.point,n.pointIndex)),c=v(n.series.key,f,l,n,T);e.tooltip.show([u,a],c,n.value<0?"n":"s",null,o)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+u.left,e.pos[1]+u.top],S.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),n.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+u.left,e.pos[1]+u.top],S.tooltipShow(e)}),n.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),S.on("tooltipHide",function(){d&&e.tooltip.cleanup()}),T.dispatch=S,T.legend=o,T.lines=t,T.bars=n,T.xAxis=r,T.y1Axis=i,T.y2Axis=s,d3.rebind(T,t,"defined","size","clipVoronoi","interpolate"),T.options=e.utils.optionsFunc.bind(T),T.x=function(e){return arguments.length?(l=e,t.x(e),n.x(e),T):l},T.y=function(e){return arguments.length?(c=e,t.y(e),n.y(e),T):c},T.margin=function(e){return arguments.length?(u.top=typeof e.top!="undefined"?e.top:u.top,u.right=typeof e.right!="undefined"?e.right:u.right,u.bottom=typeof e.bottom!="undefined"?e.bottom:u.bottom,u.left=typeof e.left!="undefined"?e.left:u.left,T):u},T.width=function(e){return arguments.length?(a=e,T):a},T.height=function(e){return arguments.length?(f=e,T):f},T.color=function(t){return arguments.length?(h=e.utils.getColor(t),o.color(h),T):h},T.showLegend=function(e){return arguments.length?(p=e,T):p},T.tooltips=function(e){return arguments.length?(d=e,T):d},T.tooltipContent=function(e){return arguments.length?(v=e,T):v},T.state=function(e){return arguments.length?(b=e,T):b},T.defaultState=function(e){return arguments.length?(w=e,T):w},T.noData=function(e){return arguments.length?(E=e,T):E},T},e.models.lineWithFocusChart=function(){"use strict";function k(e){return e.each(function(e){function U(e){var t=+(e=="e"),n=t?1:-1,r=M/3;return"M"+.5*n+","+r+"A6,6 0 0 "+t+" "+6.5*n+","+(r+6)+"V"+(2*r-6)+"A6,6 0 0 "+t+" "+.5*n+","+2*r+"Z"+"M"+2.5*n+","+(r+8)+"V"+(2*r-8)+"M"+4.5*n+","+(r+8)+"V"+(2*r-8)}function z(){a.empty()||a.extent(w),I.data([a.empty()?g.domain():w]).each(function(e,t){var n=g(e[0])-v.range()[0],r=v.range()[1]-g(e[1]);d3.select(this).select(".left").attr("width",n<0?0:n),d3.select(this).select(".right").attr("x",g(e[1])).attr("width",r<0?0:r)})}function W(){w=a.empty()?null:a.extent();var n=a.empty()?g.domain():a.extent();if(Math.abs(n[0]-n[1])<=1)return;T.brush({extent:n,brush:a}),z();var s=H.select(".nv-focus .nv-linesWrap").datum(e.filter(function(e){return!e.disabled}).map(function(e,r){return{key:e.key,values:e.values.filter(function(e,r){return t.x()(e,r)>=n[0]&&t.x()(e,r)<=n[1]})}}));s.transition().duration(N).call(t),H.select(".nv-focus .nv-x.nv-axis").transition().duration(N).call(r),H.select(".nv-focus .nv-y.nv-axis").transition().duration(N).call(i)}var S=d3.select(this),L=this,A=(h||parseInt(S.style("width"))||960)-f.left-f.right,O=(p||parseInt(S.style("height"))||400)-f.top-f.bottom-d,M=d-l.top-l.bottom;k.update=function(){S.transition().duration(N).call(k)},k.container=this;if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var _=S.selectAll(".nv-noData").data([x]);return _.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),_.attr("x",f.left+A/2).attr("y",f.top+O/2).text(function(e){return e}),k}S.selectAll(".nv-noData").remove(),v=t.xScale(),m=t.yScale(),g=n.xScale(),y=n.yScale();var D=S.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([e]),P=D.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),H=D.select("g");P.append("g").attr("class","nv-legendWrap");var B=P.append("g").attr("class","nv-focus");B.append("g").attr("class","nv-x nv-axis"),B.append("g").attr("class","nv-y nv-axis"),B.append("g").attr("class","nv-linesWrap");var j=P.append("g").attr("class","nv-context");j.append("g").attr("class","nv-x nv-axis"),j.append("g").attr("class","nv-y nv-axis"),j.append("g").attr("class","nv-linesWrap"),j.append("g").attr("class","nv-brushBackground"),j.append("g").attr("class","nv-x nv-brush"),b&&(u.width(A),H.select(".nv-legendWrap").datum(e).call(u),f.top!=u.height()&&(f.top=u.height(),O=(p||parseInt(S.style("height"))||400)-f.top-f.bottom-d),H.select(".nv-legendWrap").attr("transform","translate(0,"+ -f.top+")")),D.attr("transform","translate("+f.left+","+f.top+")"),t.width(A).height(O).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),n.defined(t.defined()).width(A).height(M).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),H.select(".nv-context").attr("transform","translate(0,"+(O+f.bottom+l.top)+")");var F=H.select(".nv-context .nv-linesWrap").datum(e.filter(function(e){return!e.disabled}));d3.transition(F).call(n),r.scale(v).ticks(A/100).tickSize(-O,0),i.scale(m).ticks(O/36).tickSize(-A,0),H.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+O+")"),a.x(g).on("brush",function(){var e=k.transitionDuration();k.transitionDuration(0),W(),k.transitionDuration(e)}),w&&a.extent(w);var I=H.select(".nv-brushBackground").selectAll("g").data([w||a.extent()]),q=I.enter().append("g");q.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),q.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var R=H.select(".nv-x.nv-brush").call(a);R.selectAll("rect").attr("height",M),R.selectAll(".resize").append("path").attr("d",U),W(),s.scale(g).ticks(A/100).tickSize(-M,0),H.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+y.range()[0]+")"),d3.transition(H.select(".nv-context .nv-x.nv-axis")).call(s),o.scale(y).ticks(M/36).tickSize(-A,0),d3.transition(H.select(".nv-context .nv-y.nv-axis")).call(o),H.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+y.range()[0]+")"),u.dispatch.on("stateChange",function(e){k.update()}),T.on("tooltipShow",function(e){E&&C(e,L.parentNode)})}),k}var t=e.models.line(),n=e.models.line(),r=e.models.axis(),i=e.models.axis(),s=e.models.axis(),o=e.models.axis(),u=e.models.legend(),a=d3.svg.brush(),f={top:30,right:30,bottom:30,left:60},l={top:0,right:30,bottom:20,left:60},c=e.utils.defaultColor(),h=null,p=null,d=100,v,m,g,y,b=!0,w=null,E=!0,S=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},x="No Data Available.",T=d3.dispatch("tooltipShow","tooltipHide","brush"),N=250;t.clipEdge(!0),n.interactive(!1),r.orient("bottom").tickPadding(5),i.orient("left"),s.orient("bottom").tickPadding(5),o.orient("left");var C=function(n,s){var o=n.pos[0]+(s.offsetLeft||0),u=n.pos[1]+(s.offsetTop||0),a=r.tickFormat()(t.x()(n.point,n.pointIndex)),f=i.tickFormat()(t.y()(n.point,n.pointIndex)),l=S(n.series.key,a,f,n,k);e.tooltip.show([o,u],l,null,null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+f.left,e.pos[1]+f.top],T.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),T.on("tooltipHide",function(){E&&e.tooltip.cleanup()}),k.dispatch=T,k.legend=u,k.lines=t,k.lines2=n,k.xAxis=r,k.yAxis=i,k.x2Axis=s,k.y2Axis=o,d3.rebind(k,t,"defined","isArea","size","xDomain","yDomain","xRange","yRange","forceX","forceY","interactive","clipEdge","clipVoronoi","id"),k.options=e.utils.optionsFunc.bind(k),k.x=function(e){return arguments.length?(t.x(e),n.x(e),k):t.x},k.y=function(e){return arguments.length?(t.y(e),n.y(e),k):t.y},k.margin=function(e){return arguments.length?(f.top=typeof e.top!="undefined"?e.top:f.top,f.right=typeof e.right!="undefined"?e.right:f.right,f.bottom=typeof e.bottom!="undefined"?e.bottom:f.bottom,f.left=typeof e.left!="undefined"?e.left:f.left,k):f},k.margin2=function(e){return arguments.length?(l=e,k):l},k.width=function(e){return arguments.length?(h=e,k):h},k.height=function(e){return arguments.length?(p=e,k):p},k.height2=function(e){return arguments.length?(d=e,k):d},k.color=function(t){return arguments.length?(c=e.utils.getColor(t),u.color(c),k):c},k.showLegend=function(e){return arguments.length?(b=e,k):b},k.tooltips=function(e){return arguments.length?(E=e,k):E},k.tooltipContent=function(e){return arguments.length?(S=e,k):S},k.interpolate=function(e){return arguments.length?(t.interpolate(e),n.interpolate(e),k):t.interpolate()},k.noData=function(e){return arguments.length?(x=e,k):x},k.xTickFormat=function(e){return arguments.length?(r.tickFormat(e),s.tickFormat(e),k):r.tickFormat()},k.yTickFormat=function(e){return arguments.length?(i.tickFormat(e),o.tickFormat(e),k):i.tickFormat()},k.brushExtent=function(e){return arguments.length?(w=e,k):w},k.transitionDuration=function(e){return arguments.length?(N=e,k):N},k},e.models.linePlusBarWithFocusChart=function(){"use strict";function B(e){return e.each(function(e){function nt(e){var t=+(e=="e"),n=t?1:-1,r=q/3;return"M"+.5*n+","+r+"A6,6 0 0 "+t+" "+6.5*n+","+(r+6)+"V"+(2*r-6)+"A6,6 0 0 "+t+" "+.5*n+","+2*r+"Z"+"M"+2.5*n+","+(r+8)+"V"+(2*r-8)+"M"+4.5*n+","+(r+8)+"V"+(2*r-8)}function rt(){h.empty()||h.extent(x),Z.data([h.empty()?k.domain():x]).each(function(e,t){var n=k(e[0])-k.range()[0],r=k.range()[1]-k(e[1]);d3.select(this).select(".left").attr("width",n<0?0:n),d3.select(this).select(".right").attr("x",k(e[1])).attr("width",r<0?0:r)})}function it(){x=h.empty()?null:h.extent(),S=h.empty()?k.domain():h.extent(),D.brush({extent:S,brush:h}),rt(),r.width(F).height(I).color(e.map(function(e,t){return e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&e[n].bar})),t.width(F).height(I).color(e.map(function(e,t){return e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&!e[n].bar}));var n=J.select(".nv-focus .nv-barsWrap").datum(U.length?U.map(function(e,t){return{key:e.key,values:e.values.filter(function(e,t){return r.x()(e,t)>=S[0]&&r.x()(e,t)<=S[1]})}}):[{values:[]}]),i=J.select(".nv-focus .nv-linesWrap").datum(z[0].disabled?[{values:[]}]:z.map(function(e,n){return{key:e.key,values:e.values.filter(function(e,n){return t.x()(e,n)>=S[0]&&t.x()(e,n)<=S[1]})}}));U.length?C=r.xScale():C=t.xScale(),s.scale(C).ticks(F/100).tickSize(-I,0),s.domain([Math.ceil(S[0]),Math.floor(S[1])]),J.select(".nv-x.nv-axis").transition().duration(P).call(s),n.transition().duration(P).call(r),i.transition().duration(P).call(t),J.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L.range()[0]+")"),u.scale(L).ticks(I/36).tickSize(-F,0),J.select(".nv-focus .nv-y1.nv-axis").style("opacity",U.length?1:0),a.scale(A).ticks(I/36).tickSize(U.length?0:-F,0),J.select(".nv-focus .nv-y2.nv-axis").style("opacity",z.length?1:0).attr("transform","translate("+C.range()[1]+",0)"),J.select(".nv-focus .nv-y1.nv-axis").transition().duration(P).call(u),J.select(".nv-focus .nv-y2.nv-axis").transition().duration(P).call(a)}var N=d3.select(this),j=this,F=(v||parseInt(N.style("width"))||960)-p.left-p.right,I=(m||parseInt(N.style("height"))||400)-p.top-p.bottom-g,q=g-d.top-d.bottom;B.update=function(){N.transition().duration(P).call(B)},B.container=this;if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var R=N.selectAll(".nv-noData").data([_]);return R.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),R.attr("x",p.left+F/2).attr("y",p.top+I/2).text(function(e){return e}),B}N.selectAll(".nv-noData").remove();var U=e.filter(function(e){return!e.disabled&&e.bar}),z=e.filter(function(e){return!e.bar});C=r.xScale(),k=o.scale(),L=r.yScale(),A=t.yScale(),O=i.yScale(),M=n.yScale();var W=e.filter(function(e){return!e.disabled&&e.bar}).map(function(e){return e.values.map(function(e,t){return{x:y(e,t),y:b(e,t)}})}),X=e.filter(function(e){return!e.disabled&&!e.bar}).map(function(e){return e.values.map(function(e,t){return{x:y(e,t),y:b(e,t)}})});C.range([0,F]),k.domain(d3.extent(d3.merge(W.concat(X)),function(e){return e.x})).range([0,F]);var V=N.selectAll("g.nv-wrap.nv-linePlusBar").data([e]),$=V.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),J=V.select("g");$.append("g").attr("class","nv-legendWrap");var K=$.append("g").attr("class","nv-focus");K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y1 nv-axis"),K.append("g").attr("class","nv-y2 nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-linesWrap");var Q=$.append("g").attr("class","nv-context");Q.append("g").attr("class","nv-x nv-axis"),Q.append("g").attr("class","nv-y1 nv-axis"),Q.append("g").attr("class","nv-y2 nv-axis"),Q.append("g").attr("class","nv-barsWrap"),Q.append("g").attr("class","nv-linesWrap"),Q.append("g").attr("class","nv-brushBackground"),Q.append("g").attr("class","nv-x nv-brush"),E&&(c.width(F/2),J.select(".nv-legendWrap").datum(e.map(function(e){return e.originalKey=e.originalKey===undefined?e.key:e.originalKey,e.key=e.originalKey+(e.bar?" (left axis)":" (right axis)"),e})).call(c),p.top!=c.height()&&(p.top=c.height(),I=(m||parseInt(N.style("height"))||400)-p.top-p.bottom-g),J.select(".nv-legendWrap").attr("transform","translate("+F/2+","+ -p.top+")")),V.attr("transform","translate("+p.left+","+p.top+")"),i.width(F).height(q).color(e.map(function(e,t){return e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&e[n].bar})),n.width(F).height(q).color(e.map(function(e,t){return e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&!e[n].bar}));var G=J.select(".nv-context .nv-barsWrap").datum(U.length?U:[{values:[]}]),Y=J.select(".nv-context .nv-linesWrap").datum(z[0].disabled?[{values:[]}]:z);J.select(".nv-context").attr("transform","translate(0,"+(I+p.bottom+d.top)+")"),G.transition().call(i),Y.transition().call(n),h.x(k).on("brush",it),x&&h.extent(x);var Z=J.select(".nv-brushBackground").selectAll("g").data([x||h.extent()]),et=Z.enter().append("g");et.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",q),et.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",q);var tt=J.select(".nv-x.nv-brush").call(h);tt.selectAll("rect").attr("height",q),tt.selectAll(".resize").append("path").attr("d",nt),o.ticks(F/100).tickSize(-q,0),J.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+O.range()[0]+")"),J.select(".nv-context .nv-x.nv-axis").transition().call(o),f.scale(O).ticks(q/36).tickSize(-F,0),J.select(".nv-context .nv-y1.nv-axis").style("opacity",U.length?1:0).attr("transform","translate(0,"+k.range()[0]+")"),J.select(".nv-context .nv-y1.nv-axis").transition().call(f),l.scale(M).ticks(q/36).tickSize(U.length?0:-F,0),J.select(".nv-context .nv-y2.nv-axis").style("opacity",z.length?1:0).attr("transform","translate("+k.range()[1]+",0)"),J.select(".nv-context .nv-y2.nv-axis").transition().call(l),c.dispatch.on("stateChange",function(e){B.update()}),D.on("tooltipShow",function(e){T&&H(e,j.parentNode)}),it()}),B}var t=e.models.line(),n=e.models.line(),r=e.models.historicalBar(),i=e.models.historicalBar(),s=e.models.axis(),o=e.models.axis(),u=e.models.axis(),a=e.models.axis(),f=e.models.axis(),l=e.models.axis(),c=e.models.legend(),h=d3.svg.brush(),p={top:30,right:30,bottom:30,left:60},d={top:0,right:30,bottom:20,left:60},v=null,m=null,g=100,y=function(e){return e.x},b=function(e){return e.y},w=e.utils.defaultColor(),E=!0,S,x=null,T=!0,N=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},C,k,L,A,O,M,_="No Data Available.",D=d3.dispatch("tooltipShow","tooltipHide","brush"),P=0;t.clipEdge(!0),n.interactive(!1),s.orient("bottom").tickPadding(5),u.orient("left"),a.orient("right"),o.orient("bottom").tickPadding(5),f.orient("left"),l.orient("right");var H=function(n,r){S&&(n.pointIndex+=Math.ceil(S[0]));var i=n.pos[0]+(r.offsetLeft||0),o=n.pos[1]+(r.offsetTop||0),f=s.tickFormat()(t.x()(n.point,n.pointIndex)),l=(n.series.bar?u:a).tickFormat()(t.y()(n.point,n.pointIndex)),c=N(n.series.key,f,l,n,B);e.tooltip.show([i,o],c,n.value<0?"n":"s",null,r)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+p.left,e.pos[1]+p.top],D.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){D.tooltipHide(e)}),r.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+p.left,e.pos[1]+p.top],D.tooltipShow(e)}),r.dispatch.on("elementMouseout.tooltip",function(e){D.tooltipHide(e)}),D.on("tooltipHide",function(){T&&e.tooltip.cleanup()}),B.dispatch=D,B.legend=c,B.lines=t,B.lines2=n,B.bars=r,B.bars2=i,B.xAxis=s,B.x2Axis=o,B.y1Axis=u,B.y2Axis=a,B.y3Axis=f,B.y4Axis=l,d3.rebind(B,t,"defined","size","clipVoronoi","interpolate"),B.options=e.utils.optionsFunc.bind(B),B.x=function(e){return arguments.length?(y=e,t.x(e),r.x(e),B):y},B.y=function(e){return arguments.length?(b=e,t.y(e),r.y(e),B):b},B.margin=function(e){return arguments.length?(p.top=typeof e.top!="undefined"?e.top:p.top,p.right=typeof e.right!="undefined"?e.right:p.right,p.bottom=typeof e.bottom!="undefined"?e.bottom:p.bottom,p.left=typeof e.left!="undefined"?e.left:p.left,B):p},B.width=function(e){return arguments.length?(v=e,B):v},B.height=function(e){return arguments.length?(m=e,B):m},B.color=function(t){return arguments.length?(w=e.utils.getColor(t),c.color(w),B):w},B.showLegend=function(e){return arguments.length?(E=e,B):E},B.tooltips=function(e){return arguments.length?(T=e,B):T},B.tooltipContent=function(e){return arguments.length?(N=e,B):N},B.noData=function(e){return arguments.length?(_=e,B):_},B.brushExtent=function(e){return arguments.length?(x=e,B):x},B},e.models.multiBar=function(){"use strict";function C(e){return e.each(function(e){var C=n-t.left-t.right,k=r-t.top-t.bottom,L=d3.select(this);d&&e.length&&(d=[{values:e[0].values.map(function(e){return{x:e.x,y:0,series:e.series,size:.01}})}]),c&&(e=d3.layout.stack().offset(h).values(function(e){return e.values}).y(a)(!e.length&&d?d:e)),e.forEach(function(e,t){e.values.forEach(function(e){e.series=t})}),c&&e[0].values.map(function(t,n){var r=0,i=0;e.map(function(e){var t=e.values[n];t.size=Math.abs(t.y),t.y<0?(t.y1=i,i-=t.size):(t.y1=t.size+r,r+=t.size)})});var A=y&&b?[]:e.map(function(e){return e.values.map(function(e,t){return{x:u(e,t),y:a(e,t),y0:e.y0,y1:e.y1}})});i.domain(y||d3.merge(A).map(function(e){return e.x})).rangeBands(w||[0,C],S),s.domain(b||d3.extent(d3.merge(A).map(function(e){return c?e.y>0?e.y1:e.y1+e.y:e.y}).concat(f))).range(E||[k,0]),i.domain()[0]===i.domain()[1]&&(i.domain()[0]?i.domain([i.domain()[0]-i.domain()[0]*.01,i.domain()[1]+i.domain()[1]*.01]):i.domain([-1,1])),s.domain()[0]===s.domain()[1]&&(s.domain()[0]?s.domain([s.domain()[0]+s.domain()[0]*.01,s.domain()[1]-s.domain()[1]*.01]):s.domain([-1,1])),T=T||i,N=N||s;var O=L.selectAll("g.nv-wrap.nv-multibar").data([e]),M=O.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),_=M.append("defs"),D=M.append("g"),P=O.select("g");D.append("g").attr("class","nv-groups"),O.attr("transform","translate("+t.left+","+t.top+")"),_.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),O.select("#nv-edge-clip-"+o+" rect").attr("width",C).attr("height",k),P.attr("clip-path",l?"url(#nv-edge-clip-"+o+")":"");var H=O.select(".nv-groups").selectAll(".nv-group").data(function(e){return e},function(e,t){return t});H.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),H.exit().transition().selectAll("rect.nv-bar").delay(function(t,n){return n*g/e[0].values.length}).attr("y",function(e){return c?N(e.y0):N(0)}).attr("height",0).remove(),H.attr("class",function(e,t){return"nv-group nv-series-"+t}).classed("hover",function(e){return e.hover}).style("fill",function(e,t){return p(e,t)}).style("stroke",function(e,t){return p(e,t)}),H.transition().style("stroke-opacity",1).style("fill-opacity",.75);var B=H.selectAll("rect.nv-bar").data(function(t){return d&&!e.length?d.values:t.values});B.exit().remove();var j=B.enter().append("rect").attr("class",function(e,t){return a(e,t)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(t,n,r){return c?0:r*i.rangeBand()/e.length}).attr("y",function(e){return N(c?e.y0:0)}).attr("height",0).attr("width",i.rangeBand()/(c?1:e.length)).attr("transform",function(e,t){return"translate("+i(u(e,t))+",0)"});B.style("fill",function(e,t,n){return p(e,n,t)}).style("stroke",function(e,t,n){return p(e,n,t)}).on("mouseover",function(t,n){d3.select(this).classed("hover",!0),x.elementMouseover({value:a(t,n),point:t,series:e[t.series],pos:[i(u(t,n))+i.rangeBand()*(c?e.length/2:t.series+.5)/e.length,s(a(t,n)+(c?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),x.elementMouseout({value:a(t,n),point:t,series:e[t.series],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("click",function(t,n){x.elementClick({value:a(t,n),point:t,series:e[t.series],pos:[i(u(t,n))+i.rangeBand()*(c?e.length/2:t.series+.5)/e.length
,s(a(t,n)+(c?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(t,n){x.elementDblClick({value:a(t,n),point:t,series:e[t.series],pos:[i(u(t,n))+i.rangeBand()*(c?e.length/2:t.series+.5)/e.length,s(a(t,n)+(c?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}),B.attr("class",function(e,t){return a(e,t)<0?"nv-bar negative":"nv-bar positive"}).transition().attr("transform",function(e,t){return"translate("+i(u(e,t))+",0)"}),v&&(m||(m=e.map(function(){return!0})),B.style("fill",function(e,t,n){return d3.rgb(v(e,t)).darker(m.map(function(e,t){return t}).filter(function(e,t){return!m[t]})[n]).toString()}).style("stroke",function(e,t,n){return d3.rgb(v(e,t)).darker(m.map(function(e,t){return t}).filter(function(e,t){return!m[t]})[n]).toString()})),c?B.transition().delay(function(t,n){return n*g/e[0].values.length}).attr("y",function(e,t){return s(c?e.y1:0)}).attr("height",function(e,t){return Math.max(Math.abs(s(e.y+(c?e.y0:0))-s(c?e.y0:0)),1)}).attr("x",function(t,n){return c?0:t.series*i.rangeBand()/e.length}).attr("width",i.rangeBand()/(c?1:e.length)):B.transition().delay(function(t,n){return n*g/e[0].values.length}).attr("x",function(t,n){return t.series*i.rangeBand()/e.length}).attr("width",i.rangeBand()/e.length).attr("y",function(e,t){return a(e,t)<0?s(0):s(0)-s(a(e,t))<1?s(0)-1:s(a(e,t))||0}).attr("height",function(e,t){return Math.max(Math.abs(s(a(e,t))-s(0)),1)||0}),T=i.copy(),N=s.copy()}),C}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=d3.scale.ordinal(),s=d3.scale.linear(),o=Math.floor(Math.random()*1e4),u=function(e){return e.x},a=function(e){return e.y},f=[0],l=!0,c=!1,h="zero",p=e.utils.defaultColor(),d=!1,v=null,m,g=1200,y,b,w,E,S=.1,x=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout"),T,N;return C.dispatch=x,C.options=e.utils.optionsFunc.bind(C),C.x=function(e){return arguments.length?(u=e,C):u},C.y=function(e){return arguments.length?(a=e,C):a},C.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,C):t},C.width=function(e){return arguments.length?(n=e,C):n},C.height=function(e){return arguments.length?(r=e,C):r},C.xScale=function(e){return arguments.length?(i=e,C):i},C.yScale=function(e){return arguments.length?(s=e,C):s},C.xDomain=function(e){return arguments.length?(y=e,C):y},C.yDomain=function(e){return arguments.length?(b=e,C):b},C.xRange=function(e){return arguments.length?(w=e,C):w},C.yRange=function(e){return arguments.length?(E=e,C):E},C.forceY=function(e){return arguments.length?(f=e,C):f},C.stacked=function(e){return arguments.length?(c=e,C):c},C.stackOffset=function(e){return arguments.length?(h=e,C):h},C.clipEdge=function(e){return arguments.length?(l=e,C):l},C.color=function(t){return arguments.length?(p=e.utils.getColor(t),C):p},C.barColor=function(t){return arguments.length?(v=e.utils.getColor(t),C):v},C.disabled=function(e){return arguments.length?(m=e,C):m},C.id=function(e){return arguments.length?(o=e,C):o},C.hideable=function(e){return arguments.length?(d=e,C):d},C.delay=function(e){return arguments.length?(g=e,C):g},C.groupSpacing=function(e){return arguments.length?(S=e,C):S},C},e.models.multiBarChart=function(){"use strict";function A(e){return e.each(function(e){var b=d3.select(this),O=this,M=(u||parseInt(b.style("width"))||960)-o.left-o.right,_=(a||parseInt(b.style("height"))||400)-o.top-o.bottom;A.update=function(){b.transition().duration(k).call(A)},A.container=this,S.disabled=e.map(function(e){return!!e.disabled});if(!x){var D;x={};for(D in S)S[D]instanceof Array?x[D]=S[D].slice(0):x[D]=S[D]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var P=b.selectAll(".nv-noData").data([T]);return P.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),P.attr("x",o.left+M/2).attr("y",o.top+_/2).text(function(e){return e}),A}b.selectAll(".nv-noData").remove(),w=t.xScale(),E=t.yScale();var H=b.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([e]),B=H.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),j=H.select("g");B.append("g").attr("class","nv-x nv-axis"),B.append("g").attr("class","nv-y nv-axis"),B.append("g").attr("class","nv-barsWrap"),B.append("g").attr("class","nv-legendWrap"),B.append("g").attr("class","nv-controlsWrap"),c&&(i.width(M-C()),t.barColor()&&e.forEach(function(e,t){e.color=d3.rgb("#ccc").darker(t*1.5).toString()}),j.select(".nv-legendWrap").datum(e).call(i),o.top!=i.height()&&(o.top=i.height(),_=(a||parseInt(b.style("height"))||400)-o.top-o.bottom),j.select(".nv-legendWrap").attr("transform","translate("+C()+","+ -o.top+")"));if(l){var F=[{key:"Grouped",disabled:t.stacked()},{key:"Stacked",disabled:!t.stacked()}];s.width(C()).color(["#444","#444","#444"]),j.select(".nv-controlsWrap").datum(F).attr("transform","translate(0,"+ -o.top+")").call(s)}H.attr("transform","translate("+o.left+","+o.top+")"),d&&j.select(".nv-y.nv-axis").attr("transform","translate("+M+",0)"),t.disabled(e.map(function(e){return e.disabled})).width(M).height(_).color(e.map(function(e,t){return e.color||f(e,t)}).filter(function(t,n){return!e[n].disabled}));var I=j.select(".nv-barsWrap").datum(e.filter(function(e){return!e.disabled}));I.transition().call(t);if(h){n.scale(w).ticks(M/100).tickSize(-_,0),j.select(".nv-x.nv-axis").attr("transform","translate(0,"+E.range()[0]+")"),j.select(".nv-x.nv-axis").transition().call(n);var q=j.select(".nv-x.nv-axis > g").selectAll("g");q.selectAll("line, text").style("opacity",1);if(m){var R=function(e,t){return"translate("+e+","+t+")"},U=5,z=17;q.selectAll("text").attr("transform",function(e,t,n){return R(0,n%2==0?U:z)});var W=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;j.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(e,t){return R(0,t===0||W%2!==0?z:U)})}v&&q.filter(function(t,n){return n%Math.ceil(e[0].values.length/(M/100))!==0}).selectAll("text, line").style("opacity",0),g&&q.selectAll(".tick text").attr("transform","rotate("+g+" 0,0)").style("text-anchor",g>0?"start":"end"),j.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}p&&(r.scale(E).ticks(_/36).tickSize(-M,0),j.select(".nv-y.nv-axis").transition().call(r)),i.dispatch.on("stateChange",function(e){S=e,N.stateChange(S),A.update()}),s.dispatch.on("legendClick",function(e,n){if(!e.disabled)return;F=F.map(function(e){return e.disabled=!0,e}),e.disabled=!1;switch(e.key){case"Grouped":t.stacked(!1);break;case"Stacked":t.stacked(!0)}S.stacked=t.stacked(),N.stateChange(S),A.update()}),N.on("tooltipShow",function(e){y&&L(e,O.parentNode)}),N.on("changeState",function(n){typeof n.disabled!="undefined"&&(e.forEach(function(e,t){e.disabled=n.disabled[t]}),S.disabled=n.disabled),typeof n.stacked!="undefined"&&(t.stacked(n.stacked),S.stacked=n.stacked),A.update()})}),A}var t=e.models.multiBar(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o={top:30,right:20,bottom:50,left:60},u=null,a=null,f=e.utils.defaultColor(),l=!0,c=!0,h=!0,p=!0,d=!1,v=!0,m=!1,g=0,y=!0,b=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" on "+t+"</p>"},w,E,S={stacked:!1},x=null,T="No Data Available.",N=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),C=function(){return l?180:0},k=250;t.stacked(!1),n.orient("bottom").tickPadding(7).highlightZero(!0).showMaxMin(!1).tickFormat(function(e){return e}),r.orient(d?"right":"left").tickFormat(d3.format(",.1f")),s.updateState(!1);var L=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=b(i.series.key,a,f,i,A);e.tooltip.show([o,u],l,i.value<0?"n":"s",null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+o.left,e.pos[1]+o.top],N.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){N.tooltipHide(e)}),N.on("tooltipHide",function(){y&&e.tooltip.cleanup()}),A.dispatch=N,A.multibar=t,A.legend=i,A.xAxis=n,A.yAxis=r,d3.rebind(A,t,"x","y","xDomain","yDomain","xRange","yRange","forceX","forceY","clipEdge","id","stacked","stackOffset","delay","barColor","groupSpacing"),A.options=e.utils.optionsFunc.bind(A),A.margin=function(e){return arguments.length?(o.top=typeof e.top!="undefined"?e.top:o.top,o.right=typeof e.right!="undefined"?e.right:o.right,o.bottom=typeof e.bottom!="undefined"?e.bottom:o.bottom,o.left=typeof e.left!="undefined"?e.left:o.left,A):o},A.width=function(e){return arguments.length?(u=e,A):u},A.height=function(e){return arguments.length?(a=e,A):a},A.color=function(t){return arguments.length?(f=e.utils.getColor(t),i.color(f),A):f},A.showControls=function(e){return arguments.length?(l=e,A):l},A.showLegend=function(e){return arguments.length?(c=e,A):c},A.showXAxis=function(e){return arguments.length?(h=e,A):h},A.showYAxis=function(e){return arguments.length?(p=e,A):p},A.rightAlignYAxis=function(e){return arguments.length?(d=e,r.orient(e?"right":"left"),A):d},A.reduceXTicks=function(e){return arguments.length?(v=e,A):v},A.rotateLabels=function(e){return arguments.length?(g=e,A):g},A.staggerLabels=function(e){return arguments.length?(m=e,A):m},A.tooltip=function(e){return arguments.length?(b=e,A):b},A.tooltips=function(e){return arguments.length?(y=e,A):y},A.tooltipContent=function(e){return arguments.length?(b=e,A):b},A.state=function(e){return arguments.length?(S=e,A):S},A.defaultState=function(e){return arguments.length?(x=e,A):x},A.noData=function(e){return arguments.length?(T=e,A):T},A.transitionDuration=function(e){return arguments.length?(k=e,A):k},A},e.models.multiBarHorizontal=function(){"use strict";function C(e){return e.each(function(e){var i=n-t.left-t.right,y=r-t.top-t.bottom,C=d3.select(this);p&&(e=d3.layout.stack().offset("zero").values(function(e){return e.values}).y(a)(e)),e.forEach(function(e,t){e.values.forEach(function(e){e.series=t})}),p&&e[0].values.map(function(t,n){var r=0,i=0;e.map(function(e){var t=e.values[n];t.size=Math.abs(t.y),t.y<0?(t.y1=i-t.size,i-=t.size):(t.y1=r,r+=t.size)})});var k=b&&w?[]:e.map(function(e){return e.values.map(function(e,t){return{x:u(e,t),y:a(e,t),y0:e.y0,y1:e.y1}})});s.domain(b||d3.merge(k).map(function(e){return e.x})).rangeBands(E||[0,y],.1),o.domain(w||d3.extent(d3.merge(k).map(function(e){return p?e.y>0?e.y1+e.y:e.y1:e.y}).concat(f))),d&&!p?o.range(S||[o.domain()[0]<0?m:0,i-(o.domain()[1]>0?m:0)]):o.range(S||[0,i]),T=T||s,N=N||d3.scale.linear().domain(o.domain()).range([o(0),o(0)]);var L=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([e]),A=L.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),O=A.append("defs"),M=A.append("g"),_=L.select("g");M.append("g").attr("class","nv-groups"),L.attr("transform","translate("+t.left+","+t.top+")");var D=L.select(".nv-groups").selectAll(".nv-group").data(function(e){return e},function(e,t){return t});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().transition().style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(e,t){return"nv-group nv-series-"+t}).classed("hover",function(e){return e.hover}).style("fill",function(e,t){return l(e,t)}).style("stroke",function(e,t){return l(e,t)}),D.transition().style("stroke-opacity",1).style("fill-opacity",.75);var P=D.selectAll("g.nv-bar").data(function(e){return e.values});P.exit().remove();var H=P.enter().append("g").attr("transform",function(t,n,r){return"translate("+N(p?t.y0:0)+","+(p?0:r*s.rangeBand()/e.length+s(u(t,n)))+")"});H.append("rect").attr("width",0).attr("height",s.rangeBand()/(p?1:e.length)),P.on("mouseover",function(t,n){d3.select(this).classed("hover",!0),x.elementMouseover({value:a(t,n),point:t,series:e[t.series],pos:[o(a(t,n)+(p?t.y0:0)),s(u(t,n))+s.rangeBand()*(p?e.length/2:t.series+.5)/e.length],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),x.elementMouseout({value:a(t,n),point:t,series:e[t.series],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("click",function(t,n){x.elementClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(p?e.length/2:t.series+.5)/e.length,o(a(t,n)+(p?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(t,n){x.elementDblClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(p?e.length/2:t.series+.5)/e.length,o(a(t,n)+(p?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}),H.append("text"),d&&!p?(P.select("text").attr("text-anchor",function(e,t){return a(e,t)<0?"end":"start"}).attr("y",s.rangeBand()/(e.length*2)).attr("dy",".32em").text(function(e,t){return g(a(e,t))}),P.transition().select("text").attr("x",function(e,t){return a(e,t)<0?-4:o(a(e,t))-o(0)+4})):P.selectAll("text").text(""),v&&!p?(H.append("text").classed("nv-bar-label",!0),P.select("text.nv-bar-label").attr("text-anchor",function(e,t){return a(e,t)<0?"start":"end"}).attr("y",s.rangeBand()/(e.length*2)).attr("dy",".32em").text(function(e,t){return u(e,t)}),P.transition().select("text.nv-bar-label").attr("x",function(e,t){return a(e,t)<0?o(0)-o(a(e,t))+4:-4})):P.selectAll("text.nv-bar-label").text(""),P.attr("class",function(e,t){return a(e,t)<0?"nv-bar negative":"nv-bar positive"}),c&&(h||(h=e.map(function(){return!0})),P.style("fill",function(e,t,n){return d3.rgb(c(e,t)).darker(h.map(function(e,t){return t}).filter(function(e,t){return!h[t]})[n]).toString()}).style("stroke",function(e,t,n){return d3.rgb(c(e,t)).darker(h.map(function(e,t){return t}).filter(function(e,t){return!h[t]})[n]).toString()})),p?P.transition().attr("transform",function(e,t){return"translate("+o(e.y1)+","+s(u(e,t))+")"}).select("rect").attr("width",function(e,t){return Math.abs(o(a(e,t)+e.y0)-o(e.y0))}).attr("height",s.rangeBand()):P.transition().attr("transform",function(t,n){return"translate("+(a(t,n)<0?o(a(t,n)):o(0))+","+(t.series*s.rangeBand()/e.length+s(u(t,n)))+")"}).select("rect").attr("height",s.rangeBand()/e.length).attr("width",function(e,t){return Math.max(Math.abs(o(a(e,t))-o(0)),1)}),T=s.copy(),N=o.copy()}),C}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.ordinal(),o=d3.scale.linear(),u=function(e){return e.x},a=function(e){return e.y},f=[0],l=e.utils.defaultColor(),c=null,h,p=!1,d=!1,v=!1,m=60,g=d3.format(",.2f"),y=1200,b,w,E,S,x=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout"),T,N;return C.dispatch=x,C.options=e.utils.optionsFunc.bind(C),C.x=function(e){return arguments.length?(u=e,C):u},C.y=function(e){return arguments.length?(a=e,C):a},C.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,C):t},C.width=function(e){return arguments.length?(n=e,C):n},C.height=function(e){return arguments.length?(r=e,C):r},C.xScale=function(e){return arguments.length?(s=e,C):s},C.yScale=function(e){return arguments.length?(o=e,C):o},C.xDomain=function(e){return arguments.length?(b=e,C):b},C.yDomain=function(e){return arguments.length?(w=e,C):w},C.xRange=function(e){return arguments.length?(E=e,C):E},C.yRange=function(e){return arguments.length?(S=e,C):S},C.forceY=function(e){return arguments.length?(f=e,C):f},C.stacked=function(e){return arguments.length?(p=e,C):p},C.color=function(t){return arguments.length?(l=e.utils.getColor(t),C):l},C.barColor=function(t){return arguments.length?(c=e.utils.getColor(t),C):c},C.disabled=function(e){return arguments.length?(h=e,C):h},C.id=function(e){return arguments.length?(i=e,C):i},C.delay=function(e){return arguments.length?(y=e,C):y},C.showValues=function(e){return arguments.length?(d=e,C):d},C.showBarLabels=function(e){return arguments.length?(v=e,C):v},C.valueFormat=function(e){return arguments.length?(g=e,C):g},C.valuePadding=function(e){return arguments.length?(m=e,C):m},C},e.models.multiBarHorizontalChart=function(){"use strict";function C(e){return e.each(function(e){var d=d3.select(this),m=this,k=(u||parseInt(d.style("width"))||960)-o.left-o.right,L=(a||parseInt(d.style("height"))||400)-o.top-o.bottom;C.update=function(){d.transition().duration(T).call(C)},C.container=this,b.disabled=e.map(function(e){return!!e.disabled});if(!w){var A;w={};for(A in b)b[A]instanceof Array?w[A]=b[A].slice(0):w[A]=b[A]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var O=d.selectAll(".nv-noData").data([E]);return O.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),O.attr("x",o.left+k/2).attr("y",o.top+L/2).text(function(e){return e}),C}d.selectAll(".nv-noData").remove(),g=t.xScale(),y=t.yScale();var M=d.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([e]),_=M.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),D=M.select("g");_.append("g").attr("class","nv-x nv-axis"),_.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),_.append("g").attr("class","nv-barsWrap"),_.append("g").attr("class","nv-legendWrap"),_.append("g").attr("class","nv-controlsWrap"),c&&(i.width(k-x()),t.barColor()&&e.forEach(function(e,t){e.color=d3.rgb("#ccc").darker(t*1.5).toString()}),D.select(".nv-legendWrap").datum(e).call(i),o.top!=i.height()&&(o.top=i.height(),L=(a||parseInt(d.style("height"))||400)-o.top-o.bottom),D.select(".nv-legendWrap").attr("transform","translate("+x()+","+ -o.top+")"));if(l){var P=[{key:"Grouped",disabled:t.stacked()},{key:"Stacked",disabled:!t.stacked()}];s.width(x()).color(["#444","#444","#444"]),D.select(".nv-controlsWrap").datum(P).attr("transform","translate(0,"+ -o.top+")").call(s)}M.attr("transform","translate("+o.left+","+o.top+")"),t.disabled(e.map(function(e){return e.disabled})).width(k).height(L).color(e.map(function(e,t){return e.color||f(e,t)}).filter(function(t,n){return!e[n].disabled}));var H=D.select(".nv-barsWrap").datum(e.filter(function(e){return!e.disabled}));H.transition().call(t);if(h){n.scale(g).ticks(L/24).tickSize(-k,0),D.select(".nv-x.nv-axis").transition().call(n);var B=D.select(".nv-x.nv-axis").selectAll("g");B.selectAll("line, text")}p&&(r.scale(y).ticks(k/100).tickSize(-L,0),D.select(".nv-y.nv-axis").attr("transform","translate(0,"+L+")"),D.select(".nv-y.nv-axis").transition().call(r)),D.select(".nv-zeroLine line").attr("x1",y(0)).attr("x2",y(0)).attr("y1",0).attr("y2",-L),i.dispatch.on("stateChange",function(e){b=e,S.stateChange(b),C.update()}),s.dispatch.on("legendClick",function(e,n){if(!e.disabled)return;P=P.map(function(e){return e.disabled=!0,e}),e.disabled=!1;switch(e.key){case"Grouped":t.stacked(!1);break;case"Stacked":t.stacked(!0)}b.stacked=t.stacked(),S.stateChange(b),C.update()}),S.on("tooltipShow",function(e){v&&N(e,m.parentNode)}),S.on("changeState",function(n){typeof n.disabled!="undefined"&&(e.forEach(function(e,t){e.disabled=n.disabled[t]}),b.disabled=n.disabled),typeof n.stacked!="undefined"&&(t.stacked(n.stacked),b.stacked=n.stacked),C.update()})}),C}var t=e.models.multiBarHorizontal(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend().height(30),s=e.models.legend().height(30),o={top:30,right:20,bottom:50,left:60},u=null,a=null,f=e.utils.defaultColor(),l=!0,c=!0,h=!0,p=!0,d=!1,v=!0,m=function(e,t,n,r,i){return"<h3>"+e+" - "+t+"</h3>"+"<p>"+n+"</p>"},g,y,b={stacked:d},w=null,E="No Data Available.",S=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),x=function(){return l?180:0},T=250;t.stacked(d),n.orient("left").tickPadding(5).highlightZero(!1).showMaxMin(!1).tickFormat(function(e){return e}),r.orient("bottom").tickFormat(d3.format(",.1f")),s.updateState(!1);var N=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=m(i.series.key,a,f,i,C);e.tooltip.show([o,u],l,i.value<0?"e":"w",null,s)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+o.left,e.pos[1]+o.top],S.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),S.on("tooltipHide",function(){v&&e.tooltip.cleanup()}),C.dispatch=S,C.multibar=t,C.legend=i,C.xAxis=n,C.yAxis=r,d3.rebind(C,t,"x","y","xDomain","yDomain","xRange","yRange","forceX","forceY","clipEdge","id","delay","showValues","showBarLabels","valueFormat","stacked","barColor"),C.options=e.utils.optionsFunc.bind(C),C.margin=function(e){return arguments.length?(o.top=typeof e.top!="undefined"?e.top:o.top,o.right=typeof e.right!="undefined"?e.right:o.right,o.bottom=typeof e.bottom!="undefined"?e.bottom:o.bottom,o.left=typeof e.left!="undefined"?e.left:o.left,C):o},C.width=function(e){return arguments.length?(u=e,C):u},C.height=function(e){return arguments.length?(a=e,C):a},C.color=function(t){return arguments.length?(f=e.utils.getColor(t),i.color(f),C):f},C.showControls=function(e){return arguments.length?(l=e,C):l},C.showLegend=function(e){return arguments.length?(c=e,C):c},C.showXAxis=function(e){return arguments.length?(h=e,C):h},C.showYAxis=function(e){return arguments.length?(p=e,C):p},C.tooltip=function(e){return arguments.length?(m=e,C):m},C.tooltips=function(e){return arguments.length?(v=e,C):v},C.tooltipContent=function(e){return arguments.length?(m=e,C):m},C.state=function(e){return arguments.length?(b=e,C):b},C.defaultState=function(e){return arguments.length?(w=e,C):w},C.noData=function(e){return arguments.length?(E=e,C):E},C.transitionDuration=function(e){return arguments.length?(T=e,C):T},C},e.models.multiChart=function(){"use strict";function C(e){return e.each(function(e){var u=d3.select(this),f=this;C.update=function(){u.transition().call(C)},C.container=this;var k=(r||parseInt(u.style("width"))||960)-t.left-t.right,L=(i||parseInt(u.style("height"))||400)-t.top-t.bottom,A=e.filter(function(e){return!e.disabled&&e.type=="line"&&e.yAxis==1}),O=e.filter(function(e){return!e.disabled&&e.type=="line"&&e.yAxis==2}),M=e.filter(function(e){return!e.disabled&&e.type=="bar"&&e.yAxis==1}),_=e.filter(function(e){return!e.disabled&&e.type=="bar"&&e.yAxis==2}),D=e.filter(function(e){return!e.disabled&&e.type=="area"&&e.yAxis==1}),P=e.filter(function(e){return!e.disabled&&e.type=="area"&&e.yAxis==2}),H=e.filter(function(e){return!e.disabled&&e.yAxis==1}).map(function(e){return e.values.map(function(e,t){return{x:e.x,y:e.y}})}),B=e.filter(function(e){return!e.disabled&&e.yAxis==2}).map(function(e){return e.values.map(function(e,t){return{x:e.x,y:e.y}})});a.domain(d3.extent(d3.merge(H.concat(B)),function(e){return e.x})).range([0,k]);var j=u.selectAll("g.wrap.multiChart").data([e]),F=j.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");F.append("g").attr("class","x axis"),F.append("g").attr("class","y1 axis"),F.append("g").attr("class","y2 axis"),F.append("g").attr("class","lines1Wrap"),F.append("g").attr("class","lines2Wrap"),F.append("g").attr("class","bars1Wrap"),F.append("g").attr("class","bars2Wrap"),F.append("g").attr("class","stack1Wrap"),F.append("g").attr("class","stack2Wrap"),F.append("g").attr("class","legendWrap");var I=j.select("g");s&&(x.width(k/2),I.select(".legendWrap").datum(e.map(function(e){return e.originalKey=e.originalKey===undefined?e.key:e.originalKey,e.key=e.originalKey+(e.yAxis==1?"":" (right axis)"),e})).call(x),t.top!=x.height()&&(t.top=x.height(),L=(i||parseInt(u.style("height"))||400)-t.top-t.bottom),I.select(".legendWrap").attr("transform","translate("+k/2+","+ -t.top+")")),d.width(k).height(L).interpolate("monotone").color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==1&&e[n].type=="line"})),v.width(k).height(L).interpolate("monotone").color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==2&&e[n].type=="line"})),m.width(k).height(L).color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==1&&e[n].type=="bar"})),g.width(k).height(L).color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==2&&e[n].type=="bar"})),y.width(k).height(L).color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==1&&e[n].type=="area"})),b.width(k).height(L).color(e.map(function(e,t){return e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==2&&e[n].type=="area"})),I.attr("transform","translate("+t.left+","+t.top+")");var q=I.select(".lines1Wrap").datum(A),R=I.select(".bars1Wrap").datum(M),U=I.select(".stack1Wrap").datum(D),z=I.select(".lines2Wrap").datum(O),W=I.select(".bars2Wrap").datum(_),X=I.select(".stack2Wrap").datum(P),V=D.length?D.map(function(e){return e.values}).reduce(function(e,t){return e.map(function(e,n){return{x:e.x,y:e.y+t[n].y}})}).concat([{x:0,y:0}]):[],$=P.length?P.map(function(e){return e.values}).reduce(function(e,t){return e.map(function(e,n){return{x:e.x,y:e.y+t[n].y}})}).concat([{x:0,y:0}]):[];h.domain(l||d3.extent(d3.merge(H).concat(V),function(e){return e.y})).range([0,L]),p.domain(c||d3.extent(d3.merge(B).concat($),function(e){return e.y})).range([0,L]),d.yDomain(h.domain()),m.yDomain(h.domain()),y.yDomain(h.domain()),v.yDomain(p.domain()),g.yDomain(p.domain()),b.yDomain(p.domain()),D.length&&d3.transition(U).call(y),P.length&&d3.transition(X).call(b),M.length&&d3.transition(R).call(m),_.length&&d3.transition(W).call(g),A.length&&d3.transition(q).call(d),O.length&&d3.transition(z).call(v),w.ticks(k/100).tickSize(-L,0),I.select(".x.axis").attr("transform","translate(0,"+L+")"),d3.transition(I.select(".x.axis")).call(w),E.ticks(L/36).tickSize(-k,0),d3.transition(I.select(".y1.axis")).call(E),S.ticks(L/36).tickSize(-k,0),d3.transition(I.select(".y2.axis")).call(S),I.select(".y2.axis").style("opacity",B.length?1:0).attr("transform","translate("+a.range()[1]+",0)"),x.dispatch.on("stateChange",function(e){C.update()}),T.on("tooltipShow",function(e){o&&N(e,f.parentNode)})}),C}var t={top:30,right:20,bottom:50,left:60},n=d3.scale.category20().range(),r=null,i=null,s=!0,o=!0,u=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" at "+t+"</p>"},a,f,l,c,a=d3.scale.linear(),h=d3.scale.linear(),p=d3.scale.linear(),d=e.models.line().yScale(h),v=e.models.line().yScale(p),m=e.models.multiBar().stacked(!1).yScale(h),g=e.models.multiBar().stacked(!1).yScale(p),y=e.models.stackedArea().yScale(h),b=e.models.stackedArea().yScale(p),w=e.models.axis().scale(a).orient("bottom").tickPadding(5),E=e.models.axis().scale(h).orient("left"),S=e.models.axis().scale(p).orient("right"),x=e.models.legend().height(30),T=d3.dispatch("tooltipShow","tooltipHide"),N=function(t,n){var r=t.pos[0]+(n.offsetLeft||0),i=t.pos[1]+(n.offsetTop||0),s=w.tickFormat()(d.x()(t.point,t.pointIndex)),o=(t.series.yAxis==2?S:E).tickFormat()(d.y()(t.point,t.pointIndex)),a=u(t.series.key,s,o,t,C);e.tooltip.show([r,i],a,undefined,undefined,n.offsetParent)};return d.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),d.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),v.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),v.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),m.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),m.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),g.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),g.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),y.dispatch.on("tooltipShow",function(e){if(!Math.round(y.y()(e.point)*100))return setTimeout(function(){d3.selectAll(".point.hover").classed("hover",!1)},0),!1;e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),y.dispatch.on("tooltipHide",function(e){T.tooltipHide(e)}),b.dispatch.on("tooltipShow",function(e){if(!Math.round(b.y()(e.point)*100))return setTimeout(function(){d3.selectAll(".point.hover").classed("hover",!1)},0),!1;e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),b.dispatch.on("tooltipHide",function(e){T.tooltipHide(e)}),d.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),d.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),v.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],T.tooltipShow(e)}),v.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),T.on("tooltipHide",function(){o&&e.tooltip.cleanup()}),C.dispatch=T,C.lines1=d,C.lines2=v,C.bars1=m,C.bars2=g,C.stack1=y,C.stack2=b,C.xAxis=w,C.yAxis1=E,C.yAxis2=S,C.options=e.utils.optionsFunc.bind(C),C.x=function(e){return arguments.length?(getX=e,d.x(e),m.x(e),C):getX},C.y=function(e){return arguments.length?(getY=e,d.y(e),m.y(e),C):getY},C.yDomain1=function(e){return arguments.length?(l=e,C):l},C.yDomain2=function(e){return arguments.length?(c=e,C):c},C.margin=function(e){return arguments.length?(t=e,C):t},C.width=function(e){return arguments.length?(r=e,C):r},C.height=function(e){return arguments.length?(i=e,C):i},C.color=function(e){return arguments.length?(n=e,x.color(e),C):n},C.showLegend=function(e){return arguments.length?(s=e,C):s},C.tooltips=function(e){return arguments.length?(o=e,C):o},C.tooltipContent=function(e){return arguments.length?(u=e,C):u},C},e.models.ohlcBar=function(){"use strict";function x(e){return e.each(function(e){var g=n-t.left-t.right,x=r-t.top-t.bottom,T=d3.select(this);s.domain(y||d3.extent(e[0].values.map(u).concat(p))),v?s.range(w||[g*.5/e[0].values.length,g*(e[0].values.length-.5)/e[0].values.length]):s.range(w||[0,g]),o.domain(b||[d3.min(e[0].values.map(h).concat(d)),d3.max(e[0].values.map(c).concat(d))]).range(E||[x,0]),s.domain()[0]===s.domain()[1]&&(s.domain()[0]?s.domain([s.domain()[0]-s.domain()[0]*.01,s.domain()[1]+s.domain()[1]*.01]):s.domain([-1,1])),o.domain()[0]===o.domain()[1]&&(o.domain()[0]?o.domain([o.domain()[0]+o.domain()[0]*.01,o.domain()[1]-o.domain()[1]*.01]):o.domain([-1,1]));var N=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([e[0].values]),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),k=C.append("defs"),L=C.append("g"),A=N.select("g");L.append("g").attr("class","nv-ticks"),N.attr("transform","translate("+t.left+","+t.top+")"),T.on("click",function(e,t){S.chartClick({data:e,index:t,pos:d3.event,id:i})}),k.append("clipPath").attr("id","nv-chart-clip-path-"+i).append("rect"),N.select("#nv-chart-clip-path-"+i+" rect").attr("width",g).attr("height",x),A.attr("clip-path",m?"url(#nv-chart-clip-path-"+i+")":"");var O=N.select(".nv-ticks").selectAll(".nv-tick").data(function(e){return e});O.exit().remove();var M=O.enter().append("path").attr("class",function(e,t,n){return(f(e,t)>l(e,t)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+n+"-"+t}).attr("d",function(t,n){var r=g/e[0].values.length*.9;return"m0,0l0,"+(o(f(t,n))-o(c(t,n)))+"l"+ -r/2+",0l"+r/2+",0l0,"+(o(h(t,n))-o(f(t,n)))+"l0,"+(o(l(t,n))-o(h(t,n)))+"l"+r/2+",0l"+ -r/2+",0z"}).attr("transform",function(e,t){return"translate("+s(u(e,t))+","+o(c(e,t))+")"}).on("mouseover",function(t,n){d3.select(this).classed("hover",!0),S.elementMouseover({point:t,series:e[0],pos:[s(u(t,n)),o(a(t,n))],pointIndex:n,seriesIndex:0,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),S.elementMouseout({point:t,series:e[0],pointIndex:n,seriesIndex:0,e:d3.event})}).on("click",function(e,t){S.elementClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))],e:d3.event,id:i}),d3.event.stopPropagation()}).on("dblclick",function(e,t){S.elementDblClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))],e:d3.event,id:i}),d3.event.stopPropagation()});O.attr("class",function(e,t,n){return(f(e,t)>l(e,t)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+n+"-"+t}),d3.transition(O).attr("transform",function(e,t){return"translate("+s(u(e,t))+","+o(c(e,t))+")"}).attr("d",function(t,n){var r=g/e[0].values.length*.9;return"m0,0l0,"+(o(f(t,n))-o(c(t,n)))+"l"+ -r/2+",0l"+r/2+",0l0,"+(o(h(t,n))-o(f(t,n)))+"l0,"+(o(l(t,n))-o(h(t,n)))+"l"+r/2+",0l"+ -r/2+",0z"})}),x}var t={top:0
-,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.linear(),o=d3.scale.linear(),u=function(e){return e.x},a=function(e){return e.y},f=function(e){return e.open},l=function(e){return e.close},c=function(e){return e.high},h=function(e){return e.low},p=[],d=[],v=!1,m=!0,g=e.utils.defaultColor(),y,b,w,E,S=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout");return x.dispatch=S,x.options=e.utils.optionsFunc.bind(x),x.x=function(e){return arguments.length?(u=e,x):u},x.y=function(e){return arguments.length?(a=e,x):a},x.open=function(e){return arguments.length?(f=e,x):f},x.close=function(e){return arguments.length?(l=e,x):l},x.high=function(e){return arguments.length?(c=e,x):c},x.low=function(e){return arguments.length?(h=e,x):h},x.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,x):t},x.width=function(e){return arguments.length?(n=e,x):n},x.height=function(e){return arguments.length?(r=e,x):r},x.xScale=function(e){return arguments.length?(s=e,x):s},x.yScale=function(e){return arguments.length?(o=e,x):o},x.xDomain=function(e){return arguments.length?(y=e,x):y},x.yDomain=function(e){return arguments.length?(b=e,x):b},x.xRange=function(e){return arguments.length?(w=e,x):w},x.yRange=function(e){return arguments.length?(E=e,x):E},x.forceX=function(e){return arguments.length?(p=e,x):p},x.forceY=function(e){return arguments.length?(d=e,x):d},x.padData=function(e){return arguments.length?(v=e,x):v},x.clipEdge=function(e){return arguments.length?(m=e,x):m},x.color=function(t){return arguments.length?(g=e.utils.getColor(t),x):g},x.id=function(e){return arguments.length?(i=e,x):i},x},e.models.pie=function(){"use strict";function S(e){return e.each(function(e){function q(e){var t=(e.startAngle+e.endAngle)*90/Math.PI-90;return t>90?t-180:t}function R(e){e.endAngle=isNaN(e.endAngle)?0:e.endAngle,e.startAngle=isNaN(e.startAngle)?0:e.startAngle,m||(e.innerRadius=0);var t=d3.interpolate(this._current,e);return this._current=t(0),function(e){return A(t(e))}}function U(e){e.innerRadius=0;var t=d3.interpolate({startAngle:0,endAngle:0},e);return function(e){return A(t(e))}}var o=n-t.left-t.right,f=r-t.top-t.bottom,S=Math.min(o,f)/2,x=S-S/5,T=d3.select(this),N=T.selectAll(".nv-wrap.nv-pie").data(e),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-pie nv-chart-"+u),k=C.append("g"),L=N.select("g");k.append("g").attr("class","nv-pie"),k.append("g").attr("class","nv-pieLabels"),N.attr("transform","translate("+t.left+","+t.top+")"),L.select(".nv-pie").attr("transform","translate("+o/2+","+f/2+")"),L.select(".nv-pieLabels").attr("transform","translate("+o/2+","+f/2+")"),T.on("click",function(e,t){E.chartClick({data:e,index:t,pos:d3.event,id:u})});var A=d3.svg.arc().outerRadius(x);y&&A.startAngle(y),b&&A.endAngle(b),m&&A.innerRadius(S*w);var O=d3.layout.pie().sort(null).value(function(e){return e.disabled?0:s(e)}),M=N.select(".nv-pie").selectAll(".nv-slice").data(O),_=N.select(".nv-pieLabels").selectAll(".nv-label").data(O);M.exit().remove(),_.exit().remove();var D=M.enter().append("g").attr("class","nv-slice").on("mouseover",function(e,t){d3.select(this).classed("hover",!0),E.elementMouseover({label:i(e.data),value:s(e.data),point:e.data,pointIndex:t,pos:[d3.event.pageX,d3.event.pageY],id:u})}).on("mouseout",function(e,t){d3.select(this).classed("hover",!1),E.elementMouseout({label:i(e.data),value:s(e.data),point:e.data,index:t,id:u})}).on("click",function(e,t){E.elementClick({label:i(e.data),value:s(e.data),point:e.data,index:t,pos:d3.event,id:u}),d3.event.stopPropagation()}).on("dblclick",function(e,t){E.elementDblClick({label:i(e.data),value:s(e.data),point:e.data,index:t,pos:d3.event,id:u}),d3.event.stopPropagation()});M.attr("fill",function(e,t){return a(e,t)}).attr("stroke",function(e,t){return a(e,t)});var P=D.append("path").each(function(e){this._current=e});M.select("path").transition().attr("d",A).attrTween("d",R);if(l){var H=d3.svg.arc().innerRadius(0);c&&(H=A),h&&(H=d3.svg.arc().outerRadius(A.outerRadius())),_.enter().append("g").classed("nv-label",!0).each(function(e,t){var n=d3.select(this);n.attr("transform",function(e){if(g){e.outerRadius=x+10,e.innerRadius=x+15;var t=(e.startAngle+e.endAngle)/2*(180/Math.PI);return(e.startAngle+e.endAngle)/2<Math.PI?t-=90:t+=90,"translate("+H.centroid(e)+") rotate("+t+")"}return e.outerRadius=S+10,e.innerRadius=S+15,"translate("+H.centroid(e)+")"}),n.append("rect").style("stroke","#fff").style("fill","#fff").attr("rx",3).attr("ry",3),n.append("text").style("text-anchor",g?(e.startAngle+e.endAngle)/2<Math.PI?"start":"end":"middle").style("fill","#000")});var B={},j=14,F=140,I=function(e){return Math.floor(e[0]/F)*F+","+Math.floor(e[1]/j)*j};_.transition().attr("transform",function(e){if(g){e.outerRadius=x+10,e.innerRadius=x+15;var t=(e.startAngle+e.endAngle)/2*(180/Math.PI);return(e.startAngle+e.endAngle)/2<Math.PI?t-=90:t+=90,"translate("+H.centroid(e)+") rotate("+t+")"}e.outerRadius=S+10,e.innerRadius=S+15;var n=H.centroid(e),r=I(n);return B[r]&&(n[1]-=j),B[I(n)]=!0,"translate("+n+")"}),_.select(".nv-label text").style("text-anchor",g?(d.startAngle+d.endAngle)/2<Math.PI?"start":"end":"middle").text(function(e,t){var n=(e.endAngle-e.startAngle)/(2*Math.PI),r={key:i(e.data),value:s(e.data),percent:d3.format("%")(n)};return e.value&&n>v?r[p]:""})}}),S}var t={top:0,right:0,bottom:0,left:0},n=500,r=500,i=function(e){return e.x},s=function(e){return e.y},o=function(e){return e.description},u=Math.floor(Math.random()*1e4),a=e.utils.defaultColor(),f=d3.format(",.2f"),l=!0,c=!0,h=!1,p="key",v=.02,m=!1,g=!1,y=!1,b=!1,w=.5,E=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout");return S.dispatch=E,S.options=e.utils.optionsFunc.bind(S),S.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,S):t},S.width=function(e){return arguments.length?(n=e,S):n},S.height=function(e){return arguments.length?(r=e,S):r},S.values=function(t){return e.log("pie.values() is no longer supported."),S},S.x=function(e){return arguments.length?(i=e,S):i},S.y=function(e){return arguments.length?(s=d3.functor(e),S):s},S.description=function(e){return arguments.length?(o=e,S):o},S.showLabels=function(e){return arguments.length?(l=e,S):l},S.labelSunbeamLayout=function(e){return arguments.length?(g=e,S):g},S.donutLabelsOutside=function(e){return arguments.length?(h=e,S):h},S.pieLabelsOutside=function(e){return arguments.length?(c=e,S):c},S.labelType=function(e){return arguments.length?(p=e,p=p||"key",S):p},S.donut=function(e){return arguments.length?(m=e,S):m},S.donutRatio=function(e){return arguments.length?(w=e,S):w},S.startAngle=function(e){return arguments.length?(y=e,S):y},S.endAngle=function(e){return arguments.length?(b=e,S):b},S.id=function(e){return arguments.length?(u=e,S):u},S.color=function(t){return arguments.length?(a=e.utils.getColor(t),S):a},S.valueFormat=function(e){return arguments.length?(f=e,S):f},S.labelThreshold=function(e){return arguments.length?(v=e,S):v},S},e.models.pieChart=function(){"use strict";function v(e){return e.each(function(e){var u=d3.select(this),a=this,f=(i||parseInt(u.style("width"))||960)-r.left-r.right,d=(s||parseInt(u.style("height"))||400)-r.top-r.bottom;v.update=function(){u.transition().call(v)},v.container=this,l.disabled=e.map(function(e){return!!e.disabled});if(!c){var m;c={};for(m in l)l[m]instanceof Array?c[m]=l[m].slice(0):c[m]=l[m]}if(!e||!e.length){var g=u.selectAll(".nv-noData").data([h]);return g.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),g.attr("x",r.left+f/2).attr("y",r.top+d/2).text(function(e){return e}),v}u.selectAll(".nv-noData").remove();var y=u.selectAll("g.nv-wrap.nv-pieChart").data([e]),b=y.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),w=y.select("g");b.append("g").attr("class","nv-pieWrap"),b.append("g").attr("class","nv-legendWrap"),o&&(n.width(f).key(t.x()),y.select(".nv-legendWrap").datum(e).call(n),r.top!=n.height()&&(r.top=n.height(),d=(s||parseInt(u.style("height"))||400)-r.top-r.bottom),y.select(".nv-legendWrap").attr("transform","translate(0,"+ -r.top+")")),y.attr("transform","translate("+r.left+","+r.top+")"),t.width(f).height(d);var E=w.select(".nv-pieWrap").datum([e]);d3.transition(E).call(t),n.dispatch.on("stateChange",function(e){l=e,p.stateChange(l),v.update()}),t.dispatch.on("elementMouseout.tooltip",function(e){p.tooltipHide(e)}),p.on("changeState",function(t){typeof t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),l.disabled=t.disabled),v.update()})}),v}var t=e.models.pie(),n=e.models.legend(),r={top:30,right:20,bottom:20,left:20},i=null,s=null,o=!0,u=e.utils.defaultColor(),a=!0,f=function(e,t,n,r){return"<h3>"+e+"</h3>"+"<p>"+t+"</p>"},l={},c=null,h="No Data Available.",p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),d=function(n,r){var i=t.description()(n.point)||t.x()(n.point),s=n.pos[0]+(r&&r.offsetLeft||0),o=n.pos[1]+(r&&r.offsetTop||0),u=t.valueFormat()(t.y()(n.point)),a=f(i,u,n,v);e.tooltip.show([s,o],a,n.value<0?"n":"s",null,r)};return t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+r.left,e.pos[1]+r.top],p.tooltipShow(e)}),p.on("tooltipShow",function(e){a&&d(e)}),p.on("tooltipHide",function(){a&&e.tooltip.cleanup()}),v.legend=n,v.dispatch=p,v.pie=t,d3.rebind(v,t,"valueFormat","values","x","y","description","id","showLabels","donutLabelsOutside","pieLabelsOutside","labelType","donut","donutRatio","labelThreshold"),v.options=e.utils.optionsFunc.bind(v),v.margin=function(e){return arguments.length?(r.top=typeof e.top!="undefined"?e.top:r.top,r.right=typeof e.right!="undefined"?e.right:r.right,r.bottom=typeof e.bottom!="undefined"?e.bottom:r.bottom,r.left=typeof e.left!="undefined"?e.left:r.left,v):r},v.width=function(e){return arguments.length?(i=e,v):i},v.height=function(e){return arguments.length?(s=e,v):s},v.color=function(r){return arguments.length?(u=e.utils.getColor(r),n.color(u),t.color(u),v):u},v.showLegend=function(e){return arguments.length?(o=e,v):o},v.tooltips=function(e){return arguments.length?(a=e,v):a},v.tooltipContent=function(e){return arguments.length?(f=e,v):f},v.state=function(e){return arguments.length?(l=e,v):l},v.defaultState=function(e){return arguments.length?(c=e,v):c},v.noData=function(e){return arguments.length?(h=e,v):h},v},e.models.scatter=function(){"use strict";function I(q){return q.each(function(I){function Q(){if(!g)return!1;var e,i=d3.merge(I.map(function(e,t){return e.values.map(function(e,n){var r=f(e,n),i=l(e,n);return[o(r)+Math.random()*1e-7,u(i)+Math.random()*1e-7,t,n,e]}).filter(function(e,t){return b(e[4],t)})}));if(D===!0){if(x){var a=X.select("defs").selectAll(".nv-point-clips").data([s]).enter();a.append("clipPath").attr("class","nv-point-clips").attr("id","nv-points-clip-"+s);var c=X.select("#nv-points-clip-"+s).selectAll("circle").data(i);c.enter().append("circle").attr("r",T),c.exit().remove(),c.attr("cx",function(e){return e[0]}).attr("cy",function(e){return e[1]}),X.select(".nv-point-paths").attr("clip-path","url(#nv-points-clip-"+s+")")}i.length&&(i.push([o.range()[0]-20,u.range()[0]-20,null,null]),i.push([o.range()[1]+20,u.range()[1]+20,null,null]),i.push([o.range()[0]-20,u.range()[0]+20,null,null]),i.push([o.range()[1]+20,u.range()[1]-20,null,null]));var h=d3.geom.polygon([[-10,-10],[-10,r+10],[n+10,r+10],[n+10,-10]]),p=d3.geom.voronoi(i).map(function(e,t){return{data:h.clip(e),series:i[t][2],point:i[t][3]}}),d=X.select(".nv-point-paths").selectAll("path").data(p);d.enter().append("path").attr("class",function(e,t){return"nv-path-"+t}),d.exit().remove(),d.attr("d",function(e){return e.data.length===0?"M 0 0":"M"+e.data.join("L")+"Z"});var v=function(e,n){if(F)return 0;var r=I[e.series];if(typeof r=="undefined")return;var i=r.values[e.point];n({point:i,series:r,pos:[o(f(i,e.point))+t.left,u(l(i,e.point))+t.top],seriesIndex:e.series,pointIndex:e.point})};d.on("click",function(e){v(e,_.elementClick)}).on("mouseover",function(e){v(e,_.elementMouseover)}).on("mouseout",function(e,t){v(e,_.elementMouseout)})}else X.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(e,n){if(F||!I[e.series])return 0;var r=I[e.series],i=r.values[n];_.elementClick({point:i,series:r,pos:[o(f(i,n))+t.left,u(l(i,n))+t.top],seriesIndex:e.series,pointIndex:n})}).on("mouseover",function(e,n){if(F||!I[e.series])return 0;var r=I[e.series],i=r.values[n];_.elementMouseover({point:i,series:r,pos:[o(f(i,n))+t.left,u(l(i,n))+t.top],seriesIndex:e.series,pointIndex:n})}).on("mouseout",function(e,t){if(F||!I[e.series])return 0;var n=I[e.series],r=n.values[t];_.elementMouseout({point:r,series:n,seriesIndex:e.series,pointIndex:t})});F=!1}var q=n-t.left-t.right,R=r-t.top-t.bottom,U=d3.select(this);I.forEach(function(e,t){e.values.forEach(function(e){e.series=t})});var W=N&&C&&A?[]:d3.merge(I.map(function(e){return e.values.map(function(e,t){return{x:f(e,t),y:l(e,t),size:c(e,t)}})}));o.domain(N||d3.extent(W.map(function(e){return e.x}).concat(d))),w&&I[0]?o.range(k||[(q*E+q)/(2*I[0].values.length),q-q*(1+E)/(2*I[0].values.length)]):o.range(k||[0,q]),u.domain(C||d3.extent(W.map(function(e){return e.y}).concat(v))).range(L||[R,0]),a.domain(A||d3.extent(W.map(function(e){return e.size}).concat(m))).range(O||[16,256]);if(o.domain()[0]===o.domain()[1]||u.domain()[0]===u.domain()[1])M=!0;o.domain()[0]===o.domain()[1]&&(o.domain()[0]?o.domain([o.domain()[0]-o.domain()[0]*.01,o.domain()[1]+o.domain()[1]*.01]):o.domain([-1,1])),u.domain()[0]===u.domain()[1]&&(u.domain()[0]?u.domain([u.domain()[0]-u.domain()[0]*.01,u.domain()[1]+u.domain()[1]*.01]):u.domain([-1,1])),isNaN(o.domain()[0])&&o.domain([-1,1]),isNaN(u.domain()[0])&&u.domain([-1,1]),P=P||o,H=H||u,B=B||a;var X=U.selectAll("g.nv-wrap.nv-scatter").data([I]),V=X.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+s+(M?" nv-single-point":"")),$=V.append("defs"),J=V.append("g"),K=X.select("g");J.append("g").attr("class","nv-groups"),J.append("g").attr("class","nv-point-paths"),X.attr("transform","translate("+t.left+","+t.top+")"),$.append("clipPath").attr("id","nv-edge-clip-"+s).append("rect"),X.select("#nv-edge-clip-"+s+" rect").attr("width",q).attr("height",R>0?R:0),K.attr("clip-path",S?"url(#nv-edge-clip-"+s+")":""),F=!0;var G=X.select(".nv-groups").selectAll(".nv-group").data(function(e){return e},function(e){return e.key});G.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),G.exit().remove(),G.attr("class",function(e,t){return"nv-group nv-series-"+t}).classed("hover",function(e){return e.hover}),G.transition().style("fill",function(e,t){return i(e,t)}).style("stroke",function(e,t){return i(e,t)}).style("stroke-opacity",1).style("fill-opacity",.5);if(p){var Y=G.selectAll("circle.nv-point").data(function(e){return e.values},y);Y.enter().append("circle").style("fill",function(e,t){return e.color}).style("stroke",function(e,t){return e.color}).attr("cx",function(t,n){return e.utils.NaNtoZero(P(f(t,n)))}).attr("cy",function(t,n){return e.utils.NaNtoZero(H(l(t,n)))}).attr("r",function(e,t){return Math.sqrt(a(c(e,t))/Math.PI)}),Y.exit().remove(),G.exit().selectAll("path.nv-point").transition().attr("cx",function(t,n){return e.utils.NaNtoZero(o(f(t,n)))}).attr("cy",function(t,n){return e.utils.NaNtoZero(u(l(t,n)))}).remove(),Y.each(function(e,t){d3.select(this).classed("nv-point",!0).classed("nv-point-"+t,!0).classed("hover",!1)}),Y.transition().attr("cx",function(t,n){return e.utils.NaNtoZero(o(f(t,n)))}).attr("cy",function(t,n){return e.utils.NaNtoZero(u(l(t,n)))}).attr("r",function(e,t){return Math.sqrt(a(c(e,t))/Math.PI)})}else{var Y=G.selectAll("path.nv-point").data(function(e){return e.values});Y.enter().append("path").style("fill",function(e,t){return e.color}).style("stroke",function(e,t){return e.color}).attr("transform",function(e,t){return"translate("+P(f(e,t))+","+H(l(e,t))+")"}).attr("d",d3.svg.symbol().type(h).size(function(e,t){return a(c(e,t))})),Y.exit().remove(),G.exit().selectAll("path.nv-point").transition().attr("transform",function(e,t){return"translate("+o(f(e,t))+","+u(l(e,t))+")"}).remove(),Y.each(function(e,t){d3.select(this).classed("nv-point",!0).classed("nv-point-"+t,!0).classed("hover",!1)}),Y.transition().attr("transform",function(e,t){return"translate("+o(f(e,t))+","+u(l(e,t))+")"}).attr("d",d3.svg.symbol().type(h).size(function(e,t){return a(c(e,t))}))}clearTimeout(j),j=setTimeout(Q,300),P=o.copy(),H=u.copy(),B=a.copy()}),I}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=e.utils.defaultColor(),s=Math.floor(Math.random()*1e5),o=d3.scale.linear(),u=d3.scale.linear(),a=d3.scale.linear(),f=function(e){return e.x},l=function(e){return e.y},c=function(e){return e.size||1},h=function(e){return e.shape||"circle"},p=!0,d=[],v=[],m=[],g=!0,y=null,b=function(e){return!e.notActive},w=!1,E=.1,S=!1,x=!0,T=function(){return 25},N=null,C=null,k=null,L=null,A=null,O=null,M=!1,_=d3.dispatch("elementClick","elementMouseover","elementMouseout"),D=!0,P,H,B,j,F=!1;return I.clearHighlights=function(){d3.selectAll(".nv-chart-"+s+" .nv-point.hover").classed("hover",!1)},I.highlightPoint=function(e,t,n){d3.select(".nv-chart-"+s+" .nv-series-"+e+" .nv-point-"+t).classed("hover",n)},_.on("elementMouseover.point",function(e){g&&I.highlightPoint(e.seriesIndex,e.pointIndex,!0)}),_.on("elementMouseout.point",function(e){g&&I.highlightPoint(e.seriesIndex,e.pointIndex,!1)}),I.dispatch=_,I.options=e.utils.optionsFunc.bind(I),I.x=function(e){return arguments.length?(f=d3.functor(e),I):f},I.y=function(e){return arguments.length?(l=d3.functor(e),I):l},I.size=function(e){return arguments.length?(c=d3.functor(e),I):c},I.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,I):t},I.width=function(e){return arguments.length?(n=e,I):n},I.height=function(e){return arguments.length?(r=e,I):r},I.xScale=function(e){return arguments.length?(o=e,I):o},I.yScale=function(e){return arguments.length?(u=e,I):u},I.zScale=function(e){return arguments.length?(a=e,I):a},I.xDomain=function(e){return arguments.length?(N=e,I):N},I.yDomain=function(e){return arguments.length?(C=e,I):C},I.sizeDomain=function(e){return arguments.length?(A=e,I):A},I.xRange=function(e){return arguments.length?(k=e,I):k},I.yRange=function(e){return arguments.length?(L=e,I):L},I.sizeRange=function(e){return arguments.length?(O=e,I):O},I.forceX=function(e){return arguments.length?(d=e,I):d},I.forceY=function(e){return arguments.length?(v=e,I):v},I.forceSize=function(e){return arguments.length?(m=e,I):m},I.interactive=function(e){return arguments.length?(g=e,I):g},I.pointKey=function(e){return arguments.length?(y=e,I):y},I.pointActive=function(e){return arguments.length?(b=e,I):b},I.padData=function(e){return arguments.length?(w=e,I):w},I.padDataOuter=function(e){return arguments.length?(E=e,I):E},I.clipEdge=function(e){return arguments.length?(S=e,I):S},I.clipVoronoi=function(e){return arguments.length?(x=e,I):x},I.useVoronoi=function(e){return arguments.length?(D=e,D===!1&&(x=!1),I):D},I.clipRadius=function(e){return arguments.length?(T=e,I):T},I.color=function(t){return arguments.length?(i=e.utils.getColor(t),I):i},I.shape=function(e){return arguments.length?(h=e,I):h},I.onlyCircles=function(e){return arguments.length?(p=e,I):p},I.id=function(e){return arguments.length?(s=e,I):s},I.singlePoint=function(e){return arguments.length?(M=e,I):M},I},e.models.scatterChart=function(){"use strict";function F(e){return e.each(function(e){function K(){if(T)return X.select(".nv-point-paths").style("pointer-events","all"),!1;X.select(".nv-point-paths").style("pointer-events","none");var i=d3.mouse(this);h.distortion(x).focus(i[0]),p.distortion(x).focus(i[1]),X.select(".nv-scatterWrap").call(t),b&&X.select(".nv-x.nv-axis").call(n),w&&X.select(".nv-y.nv-axis").call(r),X.select(".nv-distributionX").datum(e.filter(function(e){return!e.disabled})).call(o),X.select(".nv-distributionY").datum(e.filter(function(e){return!e.disabled})).call(u)}var C=d3.select(this),k=this,L=(f||parseInt(C.style("width"))||960)-a.left-a.right,I=(l||parseInt(C.style("height"))||400)-a.top-a.bottom;F.update=function(){C.transition().duration(D).call(F)},F.container=this,A.disabled=e.map(function(e){return!!e.disabled});if(!O){var q;O={};for(q in A)A[q]instanceof Array?O[q]=A[q].slice(0):O[q]=A[q]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var R=C.selectAll(".nv-noData").data([_]);return R.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),R.attr("x",a.left+L/2).attr("y",a.top+I/2).text(function(e){return e}),F}C.selectAll(".nv-noData").remove(),P=P||h,H=H||p;var U=C.selectAll("g.nv-wrap.nv-scatterChart").data([e]),z=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+t.id()),W=z.append("g"),X=U.select("g");W.append("rect").attr("class","nvd3 nv-background"),W.append("g").attr("class","nv-x nv-axis"),W.append("g").attr("class","nv-y nv-axis"),W.append("g").attr("class","nv-scatterWrap"),W.append("g").attr("class","nv-distWrap"),W.append("g").attr("class","nv-legendWrap"),W.append("g").attr("class","nv-controlsWrap");if(y){var V=S?L/2:L;i.width(V),U.select(".nv-legendWrap").datum(e).call(i),a.top!=i.height()&&(a.top=i.height(),I=(l||parseInt(C.style("height"))||400)-a.top-a.bottom),U.select(".nv-legendWrap").attr("transform","translate("+(L-V)+","+ -a.top+")")}S&&(s.width(180).color(["#444"]),X.select(".nv-controlsWrap").datum(j).attr("transform","translate(0,"+ -a.top+")").call(s)),U.attr("transform","translate("+a.left+","+a.top+")"),E&&X.select(".nv-y.nv-axis").attr("transform","translate("+L+",0)"),t.width(L).height(I).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),d!==0&&t.xDomain(null),v!==0&&t.yDomain(null),U.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t);if(d!==0){var $=h.domain()[1]-h.domain()[0];t.xDomain([h.domain()[0]-d*$,h.domain()[1]+d*$])}if(v!==0){var J=p.domain()[1]-p.domain()[0];t.yDomain([p.domain()[0]-v*J,p.domain()[1]+v*J])}(v!==0||d!==0)&&U.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),b&&(n.scale(h).ticks(n.ticks()&&n.ticks().length?n.ticks():L/100).tickSize(-I,0),X.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(n)),w&&(r.scale(p).ticks(r.ticks()&&r.ticks().length?r.ticks():I/36).tickSize(-L,0),X.select(".nv-y.nv-axis").call(r)),m&&(o.getData(t.x()).scale(h).width(L).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),W.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),X.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(e.filter(function(e){return!e.disabled})).call(o)),g&&(u.getData(t.y()).scale(p).width(I).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),W.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),X.select(".nv-distributionY").attr("transform","translate("+(E?L:-u.size())+",0)").datum(e.filter(function(e){return!e.disabled})).call(u)),d3.fisheye&&(X.select(".nv-background").attr("width",L).attr("height",I),X.select(".nv-background").on("mousemove",K),X.select(".nv-background").on("click",function(){T=!T}),t.dispatch.on("elementClick.freezeFisheye",function(){T=!T})),s.dispatch.on("legendClick",function(e,i){e.disabled=!e.disabled,x=e.disabled?0:2.5,X.select(".nv-background").style("pointer-events",e.disabled?"none":"all"),X.select(".nv-point-paths").style("pointer-events",e.disabled?"all":"none"),e.disabled?(h.distortion(x).focus(0),p.distortion(x).focus(0),X.select(".nv-scatterWrap").call(t),X.select(".nv-x.nv-axis").call(n),X.select(".nv-y.nv-axis").call(r)):T=!1,F.update()}),i.dispatch.on("stateChange",function(e){A.disabled=e.disabled,M.stateChange(A),F.update()}),t.dispatch.on("elementMouseover.tooltip",function(e){d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-distx-"+e.pointIndex).attr("y1",function(t,n){return e.pos[1]-I}),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-disty-"+e.pointIndex).attr("x2",e.pos[0]+o.size()),e.pos=[e.pos[0]+a.left,e.pos[1]+a.top],M.tooltipShow(e)}),M.on("tooltipShow",function(e){N&&B(e,k.parentNode)}),M.on("changeState",function(t){typeof t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),A.disabled=t.disabled),F.update()}),P=h.copy(),H=p.copy()}),F}var t=e.models.scatter(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o=e.models.distribution(),u=e.models.distribution(),a={top:30,right:20,bottom:50,left:75},f=null,l=null,c=e.utils.defaultColor(),h=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.xScale(),p=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.yScale(),d=0,v=0,m=!1,g=!1,y=!0,b=!0,w=!0,E=!1,S=!!d3.fisheye,x=0,T=!1,N=!0,C=function(e,t,n){return"<strong>"+t+"</strong>"},k=function(e,t,n){return"<strong>"+n+"</strong>"},L=null,A={},O=null,M=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),_="No Data Available.",D=250;t.xScale(h).yScale(p),n.orient("bottom").tickPadding(10),r.orient(E?"right":"left").tickPadding(10),o.axis("x"),u.axis("y"),s.updateState(!1);var P,H,B=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),f=i.pos[0]+(s.offsetLeft||0),l=p.range()[0]+a.top+(s.offsetTop||0),c=h.range()[0]+a.left+(s.offsetLeft||0),d=i.pos[1]+(s.offsetTop||0),v=n.tickFormat()(t.x()(i.point,i.pointIndex)),m=r.tickFormat()(t.y()(i.point,i.pointIndex));C!=null&&e.tooltip.show([f,l],C(i.series.key,v,m,i,F),"n",1,s,"x-nvtooltip"),k!=null&&e.tooltip.show([c,d],k(i.series.key,v,m,i,F),"e",1,s,"y-nvtooltip"),L!=null&&e.tooltip.show([o,u],L(i.series.key,v,m,i,F),i.value<0?"n":"s",null,s)},j=[{key:"Magnify",disabled:!0}];return t.dispatch.on("elementMouseout.tooltip",function(e){M.tooltipHide(e),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-distx-"+e.pointIndex).attr("y1",0),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-disty-"+e.pointIndex).attr("x2",u.size())}),M.on("tooltipHide",function(){N&&e.tooltip.cleanup()}),F.dispatch=M,F.scatter=t,F.legend=i,F.controls=s,F.xAxis=n,F.yAxis=r,F.distX=o,F.distY=u,d3.rebind(F,t,"id","interactive","pointActive","x","y","shape","size","xScale","yScale","zScale","xDomain","yDomain","xRange","yRange","sizeDomain","sizeRange","forceX","forceY","forceSize","clipVoronoi","clipRadius","useVoronoi"),F.options=e.utils.optionsFunc.bind(F),F.margin=function(e){return arguments.length?(a.top=typeof e.top!="undefined"?e.top:a.top,a.right=typeof e.right!="undefined"?e.right:a.right,a.bottom=typeof e.bottom!="undefined"?e.bottom:a.bottom,a.left=typeof e.left!="undefined"?e.left:a.left,F):a},F.width=function(e){return arguments.length?(f=e,F):f},F.height=function(e){return arguments.length?(l=e,F):l},F.color=function(t){return arguments.length?(c=e.utils.getColor(t),i.color(c),o.color(c),u.color(c),F):c},F.showDistX=function(e){return arguments.length?(m=e,F):m},F.showDistY=function(e){return arguments.length?(g=e,F):g},F.showControls=function(e){return arguments.length?(S=e,F):S},F.showLegend=function(e){return arguments.length?(y=e,F):y},F.showXAxis=function(e){return arguments.length?(b=e,F):b},F.showYAxis=function(e){return arguments.length?(w=e,F):w},F.rightAlignYAxis=function(e){return arguments.length?(E=e,r.orient(e?"right":"left"),F):E},F.fisheye=function(e){return arguments.length?(x=e,F):x},F.xPadding=function(e){return arguments.length?(d=e,F):d},F.yPadding=function(e){return arguments.length?(v=e,F):v},F.tooltips=function(e){return arguments.length?(N=e,F):N},F.tooltipContent=function(e){return arguments.length?(L=e,F):L},F.tooltipXContent=function(e){return arguments.length?(C=e,F):C},F.tooltipYContent=function(e){return arguments.length?(k=e,F):k},F.state=function(e){return arguments.length?(A=e,F):A},F.defaultState=function(e){return arguments.length?(O=e,F):O},F.noData=function(e){return arguments.length?(_=e,F):_},F.transitionDuration=function(e){return arguments.length?(D=e,F):D},F},e.models.scatterPlusLineChart=function(){"use strict";function B(e){return e.each(function(e){function $(){if(S)return z.select(".nv-point-paths").style("pointer-events","all"),!1;z.select(".nv-point-paths").style("pointer-events","none");var i=d3.mouse(this);h.distortion(E).focus(i[0]),p.distortion(E).focus(i[1]),z.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),g&&z.select(".nv-x.nv-axis").call(n),y&&z.select(".nv-y.nv-axis").call(r),z.select(".nv-distributionX").datum(e.filter(function(e){return!e.disabled})).call(o),z.select(".nv-distributionY").datum(e.filter(function(e){return!e.disabled})).call(u)}var T=d3.select(this),N=this,C=(f||parseInt(T.style("width"))||960)-a.left-a.right,j=(l||parseInt(T.style("height"))||400)-a.top-a.bottom;B.update=function(){T.transition().duration(M).call(B)},B.container=this,k.disabled=e.map(function(e){return!!e.disabled});if(!L){var F;L={};for(F in k)k[F]instanceof Array?L[F]=k[F].slice(0):L[F]=k[F]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var I=T.selectAll(".nv-noData").data([O]);return I.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),I.attr("x",a.left+C/2).attr("y",a.top+j/2).text(function(e){return e}),B}T.selectAll(".nv-noData").remove(),h=t.xScale(),p=t.yScale(),_=_||h,D=D||p;var q=T.selectAll("g.nv-wrap.nv-scatterChart").data([e]),R=q.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+t.id()),U=R.append("g"),z=q.select("g");U.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),U.append("g").attr("class","nv-x nv-axis"),U.append("g").attr("class","nv-y nv-axis"),U.append("g").attr("class","nv-scatterWrap"),U.append("g").attr("class","nv-regressionLinesWrap"),U.append("g").attr("class","nv-distWrap"),U.append("g").attr("class","nv-legendWrap"),U.append("g").attr("class","nv-controlsWrap"),q.attr("transform","translate("+a.left+","+a.top+")"),b&&z.select(".nv-y.nv-axis").attr("transform","translate("+C+",0)"),m&&(i.width(C/2),q.select(".nv-legendWrap").datum(e).call(i),a.top!=i.height()&&(a.top=i.height(),j=(l||parseInt(T.style("height"))||400)-a.top-a.bottom),q.select(".nv-legendWrap").attr("transform","translate("+C/2+","+ -a.top+")")),w&&(s.width(180).color(["#444"]),z.select(".nv-controlsWrap").datum(H).attr("transform","translate(0,"+ -a.top+")").call(s)),t.width(C).height(j).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),q.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),q.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+t.id()+")");var W=q.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(e){return e});W.enter().append("g").attr("class","nv-regLines");var X=W.selectAll(".nv-regLine").data(function(e){return[e]}),V=X.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0);X.transition().attr("x1",h.range()[0]).attr("x2",h.range()[1]).attr("y1",function(e,t){return p(h.domain()[0]*e.slope+e.intercept)}).attr("y2",function(e,t){return p(h.domain()[1]*e.slope+e.intercept)}).style("stroke",function(e,t,n){return c(e,n)}).style("stroke-opacity",function(e,t){return e.disabled||typeof e.slope=="undefined"||typeof e.intercept=="undefined"?0:1}),g&&(n.scale(h).ticks(n.ticks()?n.ticks():C/100).tickSize(-j,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(n)),y&&(r.scale(p).ticks(r.ticks()?r.ticks():j/36).tickSize(-C,0),z.select(".nv-y.nv-axis").call(r)),d&&(o.getData(t.x()).scale(h).width(C).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),U.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),z.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(e.filter(function(e){return!e.disabled})).call(o)),v&&(u.getData(t.y()).scale(p).width(
+,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.linear(),o=d3.scale.linear(),u=function(e){return e.x},a=function(e){return e.y},f=function(e){return e.open},l=function(e){return e.close},c=function(e){return e.high},h=function(e){return e.low},p=[],d=[],v=!1,m=!0,g=e.utils.defaultColor(),y,b,w,E,S=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout");return x.dispatch=S,x.options=e.utils.optionsFunc.bind(x),x.x=function(e){return arguments.length?(u=e,x):u},x.y=function(e){return arguments.length?(a=e,x):a},x.open=function(e){return arguments.length?(f=e,x):f},x.close=function(e){return arguments.length?(l=e,x):l},x.high=function(e){return arguments.length?(c=e,x):c},x.low=function(e){return arguments.length?(h=e,x):h},x.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,x):t},x.width=function(e){return arguments.length?(n=e,x):n},x.height=function(e){return arguments.length?(r=e,x):r},x.xScale=function(e){return arguments.length?(s=e,x):s},x.yScale=function(e){return arguments.length?(o=e,x):o},x.xDomain=function(e){return arguments.length?(y=e,x):y},x.yDomain=function(e){return arguments.length?(b=e,x):b},x.xRange=function(e){return arguments.length?(w=e,x):w},x.yRange=function(e){return arguments.length?(E=e,x):E},x.forceX=function(e){return arguments.length?(p=e,x):p},x.forceY=function(e){return arguments.length?(d=e,x):d},x.padData=function(e){return arguments.length?(v=e,x):v},x.clipEdge=function(e){return arguments.length?(m=e,x):m},x.color=function(t){return arguments.length?(g=e.utils.getColor(t),x):g},x.id=function(e){return arguments.length?(i=e,x):i},x},e.models.pie=function(){"use strict";function S(e){return e.each(function(e){function q(e){var t=(e.startAngle+e.endAngle)*90/Math.PI-90;return t>90?t-180:t}function R(e){e.endAngle=isNaN(e.endAngle)?0:e.endAngle,e.startAngle=isNaN(e.startAngle)?0:e.startAngle,m||(e.innerRadius=0);var t=d3.interpolate(this._current,e);return this._current=t(0),function(e){return A(t(e))}}function U(e){e.innerRadius=0;var t=d3.interpolate({startAngle:0,endAngle:0},e);return function(e){return A(t(e))}}var o=n-t.left-t.right,f=r-t.top-t.bottom,S=Math.min(o,f)/2,x=S-S/5,T=d3.select(this),N=T.selectAll(".nv-wrap.nv-pie").data(e),C=N.enter().append("g").attr("class","nvd3 nv-wrap nv-pie nv-chart-"+u),k=C.append("g"),L=N.select("g");k.append("g").attr("class","nv-pie"),k.append("g").attr("class","nv-pieLabels"),N.attr("transform","translate("+t.left+","+t.top+")"),L.select(".nv-pie").attr("transform","translate("+o/2+","+f/2+")"),L.select(".nv-pieLabels").attr("transform","translate("+o/2+","+f/2+")"),T.on("click",function(e,t){E.chartClick({data:e,index:t,pos:d3.event,id:u})});var A=d3.svg.arc().outerRadius(x);y&&A.startAngle(y),b&&A.endAngle(b),m&&A.innerRadius(S*w);var O=d3.layout.pie().sort(null).value(function(e){return e.disabled?0:s(e)}),M=N.select(".nv-pie").selectAll(".nv-slice").data(O),_=N.select(".nv-pieLabels").selectAll(".nv-label").data(O);M.exit().remove(),_.exit().remove();var D=M.enter().append("g").attr("class","nv-slice").on("mouseover",function(e,t){d3.select(this).classed("hover",!0),E.elementMouseover({label:i(e.data),value:s(e.data),point:e.data,pointIndex:t,pos:[d3.event.pageX,d3.event.pageY],id:u})}).on("mouseout",function(e,t){d3.select(this).classed("hover",!1),E.elementMouseout({label:i(e.data),value:s(e.data),point:e.data,index:t,id:u})}).on("click",function(e,t){E.elementClick({label:i(e.data),value:s(e.data),point:e.data,index:t,pos:d3.event,id:u}),d3.event.stopPropagation()}).on("dblclick",function(e,t){E.elementDblClick({label:i(e.data),value:s(e.data),point:e.data,index:t,pos:d3.event,id:u}),d3.event.stopPropagation()});M.attr("fill",function(e,t){return a(e,t)}).attr("stroke",function(e,t){return a(e,t)});var P=D.append("path").each(function(e){this._current=e});M.select("path").transition().attr("d",A).attrTween("d",R);if(l){var H=d3.svg.arc().innerRadius(0);c&&(H=A),h&&(H=d3.svg.arc().outerRadius(A.outerRadius())),_.enter().append("g").classed("nv-label",!0).each(function(e,t){var n=d3.select(this);n.attr("transform",function(e){if(g){e.outerRadius=x+10,e.innerRadius=x+15;var t=(e.startAngle+e.endAngle)/2*(180/Math.PI);return(e.startAngle+e.endAngle)/2<Math.PI?t-=90:t+=90,"translate("+H.centroid(e)+") rotate("+t+")"}return e.outerRadius=S+10,e.innerRadius=S+15,"translate("+H.centroid(e)+")"}),n.append("rect").style("stroke","#fff").style("fill","#fff").attr("rx",3).attr("ry",3),n.append("text").style("text-anchor",g?(e.startAngle+e.endAngle)/2<Math.PI?"start":"end":"middle").style("fill","#000")});var B={},j=14,F=140,I=function(e){return Math.floor(e[0]/F)*F+","+Math.floor(e[1]/j)*j};_.transition().attr("transform",function(e){if(g){e.outerRadius=x+10,e.innerRadius=x+15;var t=(e.startAngle+e.endAngle)/2*(180/Math.PI);return(e.startAngle+e.endAngle)/2<Math.PI?t-=90:t+=90,"translate("+H.centroid(e)+") rotate("+t+")"}e.outerRadius=S+10,e.innerRadius=S+15;var n=H.centroid(e),r=I(n);return B[r]&&(n[1]-=j),B[I(n)]=!0,"translate("+n+")"}),_.select(".nv-label text").style("text-anchor",g?(d.startAngle+d.endAngle)/2<Math.PI?"start":"end":"middle").text(function(e,t){var n=(e.endAngle-e.startAngle)/(2*Math.PI),r={key:i(e.data),value:s(e.data),percent:d3.format("%")(n)};return e.value&&n>v?r[p]:""})}}),S}var t={top:0,right:0,bottom:0,left:0},n=500,r=500,i=function(e){return e.x},s=function(e){return e.y},o=function(e){return e.description},u=Math.floor(Math.random()*1e4),a=e.utils.defaultColor(),f=d3.format(",.2f"),l=!0,c=!0,h=!1,p="key",v=.02,m=!1,g=!1,y=!1,b=!1,w=.5,E=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout");return S.dispatch=E,S.options=e.utils.optionsFunc.bind(S),S.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,S):t},S.width=function(e){return arguments.length?(n=e,S):n},S.height=function(e){return arguments.length?(r=e,S):r},S.values=function(t){return e.log("pie.values() is no longer supported."),S},S.x=function(e){return arguments.length?(i=e,S):i},S.y=function(e){return arguments.length?(s=d3.functor(e),S):s},S.description=function(e){return arguments.length?(o=e,S):o},S.showLabels=function(e){return arguments.length?(l=e,S):l},S.labelSunbeamLayout=function(e){return arguments.length?(g=e,S):g},S.donutLabelsOutside=function(e){return arguments.length?(h=e,S):h},S.pieLabelsOutside=function(e){return arguments.length?(c=e,S):c},S.labelType=function(e){return arguments.length?(p=e,p=p||"key",S):p},S.donut=function(e){return arguments.length?(m=e,S):m},S.donutRatio=function(e){return arguments.length?(w=e,S):w},S.startAngle=function(e){return arguments.length?(y=e,S):y},S.endAngle=function(e){return arguments.length?(b=e,S):b},S.id=function(e){return arguments.length?(u=e,S):u},S.color=function(t){return arguments.length?(a=e.utils.getColor(t),S):a},S.valueFormat=function(e){return arguments.length?(f=e,S):f},S.labelThreshold=function(e){return arguments.length?(v=e,S):v},S},e.models.pieChart=function(){"use strict";function v(e){return e.each(function(e){var u=d3.select(this),a=this,f=(i||parseInt(u.style("width"))||960)-r.left-r.right,d=(s||parseInt(u.style("height"))||400)-r.top-r.bottom;v.update=function(){u.transition().call(v)},v.container=this,l.disabled=e.map(function(e){return!!e.disabled});if(!c){var m;c={};for(m in l)l[m]instanceof Array?c[m]=l[m].slice(0):c[m]=l[m]}if(!e||!e.length){var g=u.selectAll(".nv-noData").data([h]);return g.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),g.attr("x",r.left+f/2).attr("y",r.top+d/2).text(function(e){return e}),v}u.selectAll(".nv-noData").remove();var y=u.selectAll("g.nv-wrap.nv-pieChart").data([e]),b=y.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),w=y.select("g");b.append("g").attr("class","nv-pieWrap"),b.append("g").attr("class","nv-legendWrap"),o&&(n.width(f).key(t.x()),y.select(".nv-legendWrap").datum(e).call(n),r.top!=n.height()&&(r.top=n.height(),d=(s||parseInt(u.style("height"))||400)-r.top-r.bottom),y.select(".nv-legendWrap").attr("transform","translate(0,"+ -r.top+")")),y.attr("transform","translate("+r.left+","+r.top+")"),t.width(f).height(d);var E=w.select(".nv-pieWrap").datum([e]);d3.transition(E).call(t),n.dispatch.on("stateChange",function(e){l=e,p.stateChange(l),v.update()}),t.dispatch.on("elementMouseout.tooltip",function(e){p.tooltipHide(e)}),p.on("changeState",function(t){typeof t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),l.disabled=t.disabled),v.update()})}),v}var t=e.models.pie(),n=e.models.legend(),r={top:30,right:20,bottom:20,left:20},i=null,s=null,o=!0,u=e.utils.defaultColor(),a=!0,f=function(e,t,n,r){return"<h3>"+e+"</h3>"+"<p>"+t+"</p>"},l={},c=null,h="No Data Available.",p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),d=function(n,r){var i=t.description()(n.point)||t.x()(n.point),s=n.pos[0]+(r&&r.offsetLeft||0),o=n.pos[1]+(r&&r.offsetTop||0),u=t.valueFormat()(t.y()(n.point)),a=f(i,u,n,v);e.tooltip.show([s,o],a,n.value<0?"n":"s",null,r)};return t.dispatch.on("elementMouseover.tooltip",function(e){}),p.on("tooltipShow",function(e){a&&d(e)}),p.on("tooltipHide",function(){a&&e.tooltip.cleanup()}),v.legend=n,v.dispatch=p,v.pie=t,d3.rebind(v,t,"valueFormat","values","x","y","description","id","showLabels","donutLabelsOutside","pieLabelsOutside","labelType","donut","donutRatio","labelThreshold"),v.options=e.utils.optionsFunc.bind(v),v.margin=function(e){return arguments.length?(r.top=typeof e.top!="undefined"?e.top:r.top,r.right=typeof e.right!="undefined"?e.right:r.right,r.bottom=typeof e.bottom!="undefined"?e.bottom:r.bottom,r.left=typeof e.left!="undefined"?e.left:r.left,v):r},v.width=function(e){return arguments.length?(i=e,v):i},v.height=function(e){return arguments.length?(s=e,v):s},v.color=function(r){return arguments.length?(u=e.utils.getColor(r),n.color(u),t.color(u),v):u},v.showLegend=function(e){return arguments.length?(o=e,v):o},v.tooltips=function(e){return arguments.length?(a=e,v):a},v.tooltipContent=function(e){return arguments.length?(f=e,v):f},v.state=function(e){return arguments.length?(l=e,v):l},v.defaultState=function(e){return arguments.length?(c=e,v):c},v.noData=function(e){return arguments.length?(h=e,v):h},v},e.models.scatter=function(){"use strict";function I(q){return q.each(function(I){function Q(){if(!g)return!1;var e,i=d3.merge(I.map(function(e,t){return e.values.map(function(e,n){var r=f(e,n),i=l(e,n);return[o(r)+Math.random()*1e-7,u(i)+Math.random()*1e-7,t,n,e]}).filter(function(e,t){return b(e[4],t)})}));if(D===!0){if(x){var a=X.select("defs").selectAll(".nv-point-clips").data([s]).enter();a.append("clipPath").attr("class","nv-point-clips").attr("id","nv-points-clip-"+s);var c=X.select("#nv-points-clip-"+s).selectAll("circle").data(i);c.enter().append("circle").attr("r",T),c.exit().remove(),c.attr("cx",function(e){return e[0]}).attr("cy",function(e){return e[1]}),X.select(".nv-point-paths").attr("clip-path","url(#nv-points-clip-"+s+")")}i.length&&(i.push([o.range()[0]-20,u.range()[0]-20,null,null]),i.push([o.range()[1]+20,u.range()[1]+20,null,null]),i.push([o.range()[0]-20,u.range()[0]+20,null,null]),i.push([o.range()[1]+20,u.range()[1]-20,null,null]));var h=d3.geom.polygon([[-10,-10],[-10,r+10],[n+10,r+10],[n+10,-10]]),p=d3.geom.voronoi(i).map(function(e,t){return{data:h.clip(e),series:i[t][2],point:i[t][3]}}),d=X.select(".nv-point-paths").selectAll("path").data(p);d.enter().append("path").attr("class",function(e,t){return"nv-path-"+t}),d.exit().remove(),d.attr("d",function(e){return e.data.length===0?"M 0 0":"M"+e.data.join("L")+"Z"});var v=function(e,n){if(F)return 0;var r=I[e.series];if(typeof r=="undefined")return;var i=r.values[e.point];n({point:i,series:r,pos:[o(f(i,e.point))+t.left,u(l(i,e.point))+t.top],seriesIndex:e.series,pointIndex:e.point})};d.on("click",function(e){v(e,_.elementClick)}).on("mouseover",function(e){v(e,_.elementMouseover)}).on("mouseout",function(e,t){v(e,_.elementMouseout)})}else X.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(e,n){if(F||!I[e.series])return 0;var r=I[e.series],i=r.values[n];_.elementClick({point:i,series:r,pos:[o(f(i,n))+t.left,u(l(i,n))+t.top],seriesIndex:e.series,pointIndex:n})}).on("mouseover",function(e,n){if(F||!I[e.series])return 0;var r=I[e.series],i=r.values[n];_.elementMouseover({point:i,series:r,pos:[o(f(i,n))+t.left,u(l(i,n))+t.top],seriesIndex:e.series,pointIndex:n})}).on("mouseout",function(e,t){if(F||!I[e.series])return 0;var n=I[e.series],r=n.values[t];_.elementMouseout({point:r,series:n,seriesIndex:e.series,pointIndex:t})});F=!1}var q=n-t.left-t.right,R=r-t.top-t.bottom,U=d3.select(this);I.forEach(function(e,t){e.values.forEach(function(e){e.series=t})});var W=N&&C&&A?[]:d3.merge(I.map(function(e){return e.values.map(function(e,t){return{x:f(e,t),y:l(e,t),size:c(e,t)}})}));o.domain(N||d3.extent(W.map(function(e){return e.x}).concat(d))),w&&I[0]?o.range(k||[(q*E+q)/(2*I[0].values.length),q-q*(1+E)/(2*I[0].values.length)]):o.range(k||[0,q]),u.domain(C||d3.extent(W.map(function(e){return e.y}).concat(v))).range(L||[R,0]),a.domain(A||d3.extent(W.map(function(e){return e.size}).concat(m))).range(O||[16,256]);if(o.domain()[0]===o.domain()[1]||u.domain()[0]===u.domain()[1])M=!0;o.domain()[0]===o.domain()[1]&&(o.domain()[0]?o.domain([o.domain()[0]-o.domain()[0]*.01,o.domain()[1]+o.domain()[1]*.01]):o.domain([-1,1])),u.domain()[0]===u.domain()[1]&&(u.domain()[0]?u.domain([u.domain()[0]-u.domain()[0]*.01,u.domain()[1]+u.domain()[1]*.01]):u.domain([-1,1])),isNaN(o.domain()[0])&&o.domain([-1,1]),isNaN(u.domain()[0])&&u.domain([-1,1]),P=P||o,H=H||u,B=B||a;var X=U.selectAll("g.nv-wrap.nv-scatter").data([I]),V=X.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+s+(M?" nv-single-point":"")),$=V.append("defs"),J=V.append("g"),K=X.select("g");J.append("g").attr("class","nv-groups"),J.append("g").attr("class","nv-point-paths"),X.attr("transform","translate("+t.left+","+t.top+")"),$.append("clipPath").attr("id","nv-edge-clip-"+s).append("rect"),X.select("#nv-edge-clip-"+s+" rect").attr("width",q).attr("height",R>0?R:0),K.attr("clip-path",S?"url(#nv-edge-clip-"+s+")":""),F=!0;var G=X.select(".nv-groups").selectAll(".nv-group").data(function(e){return e},function(e){return e.key});G.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),G.exit().remove(),G.attr("class",function(e,t){return"nv-group nv-series-"+t}).classed("hover",function(e){return e.hover}),G.transition().style("fill",function(e,t){return i(e,t)}).style("stroke",function(e,t){return i(e,t)}).style("stroke-opacity",1).style("fill-opacity",.5);if(p){var Y=G.selectAll("circle.nv-point").data(function(e){return e.values},y);Y.enter().append("circle").style("fill",function(e,t){return e.color}).style("stroke",function(e,t){return e.color}).attr("cx",function(t,n){return e.utils.NaNtoZero(P(f(t,n)))}).attr("cy",function(t,n){return e.utils.NaNtoZero(H(l(t,n)))}).attr("r",function(e,t){return Math.sqrt(a(c(e,t))/Math.PI)}),Y.exit().remove(),G.exit().selectAll("path.nv-point").transition().attr("cx",function(t,n){return e.utils.NaNtoZero(o(f(t,n)))}).attr("cy",function(t,n){return e.utils.NaNtoZero(u(l(t,n)))}).remove(),Y.each(function(e,t){d3.select(this).classed("nv-point",!0).classed("nv-point-"+t,!0).classed("hover",!1)}),Y.transition().attr("cx",function(t,n){return e.utils.NaNtoZero(o(f(t,n)))}).attr("cy",function(t,n){return e.utils.NaNtoZero(u(l(t,n)))}).attr("r",function(e,t){return Math.sqrt(a(c(e,t))/Math.PI)})}else{var Y=G.selectAll("path.nv-point").data(function(e){return e.values});Y.enter().append("path").style("fill",function(e,t){return e.color}).style("stroke",function(e,t){return e.color}).attr("transform",function(e,t){return"translate("+P(f(e,t))+","+H(l(e,t))+")"}).attr("d",d3.svg.symbol().type(h).size(function(e,t){return a(c(e,t))})),Y.exit().remove(),G.exit().selectAll("path.nv-point").transition().attr("transform",function(e,t){return"translate("+o(f(e,t))+","+u(l(e,t))+")"}).remove(),Y.each(function(e,t){d3.select(this).classed("nv-point",!0).classed("nv-point-"+t,!0).classed("hover",!1)}),Y.transition().attr("transform",function(e,t){return"translate("+o(f(e,t))+","+u(l(e,t))+")"}).attr("d",d3.svg.symbol().type(h).size(function(e,t){return a(c(e,t))}))}clearTimeout(j),j=setTimeout(Q,300),P=o.copy(),H=u.copy(),B=a.copy()}),I}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=e.utils.defaultColor(),s=Math.floor(Math.random()*1e5),o=d3.scale.linear(),u=d3.scale.linear(),a=d3.scale.linear(),f=function(e){return e.x},l=function(e){return e.y},c=function(e){return e.size||1},h=function(e){return e.shape||"circle"},p=!0,d=[],v=[],m=[],g=!0,y=null,b=function(e){return!e.notActive},w=!1,E=.1,S=!1,x=!0,T=function(){return 25},N=null,C=null,k=null,L=null,A=null,O=null,M=!1,_=d3.dispatch("elementClick","elementMouseover","elementMouseout"),D=!0,P,H,B,j,F=!1;return I.clearHighlights=function(){d3.selectAll(".nv-chart-"+s+" .nv-point.hover").classed("hover",!1)},I.highlightPoint=function(e,t,n){d3.select(".nv-chart-"+s+" .nv-series-"+e+" .nv-point-"+t).classed("hover",n)},_.on("elementMouseover.point",function(e){g&&I.highlightPoint(e.seriesIndex,e.pointIndex,!0)}),_.on("elementMouseout.point",function(e){g&&I.highlightPoint(e.seriesIndex,e.pointIndex,!1)}),I.dispatch=_,I.options=e.utils.optionsFunc.bind(I),I.x=function(e){return arguments.length?(f=d3.functor(e),I):f},I.y=function(e){return arguments.length?(l=d3.functor(e),I):l},I.size=function(e){return arguments.length?(c=d3.functor(e),I):c},I.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,I):t},I.width=function(e){return arguments.length?(n=e,I):n},I.height=function(e){return arguments.length?(r=e,I):r},I.xScale=function(e){return arguments.length?(o=e,I):o},I.yScale=function(e){return arguments.length?(u=e,I):u},I.zScale=function(e){return arguments.length?(a=e,I):a},I.xDomain=function(e){return arguments.length?(N=e,I):N},I.yDomain=function(e){return arguments.length?(C=e,I):C},I.sizeDomain=function(e){return arguments.length?(A=e,I):A},I.xRange=function(e){return arguments.length?(k=e,I):k},I.yRange=function(e){return arguments.length?(L=e,I):L},I.sizeRange=function(e){return arguments.length?(O=e,I):O},I.forceX=function(e){return arguments.length?(d=e,I):d},I.forceY=function(e){return arguments.length?(v=e,I):v},I.forceSize=function(e){return arguments.length?(m=e,I):m},I.interactive=function(e){return arguments.length?(g=e,I):g},I.pointKey=function(e){return arguments.length?(y=e,I):y},I.pointActive=function(e){return arguments.length?(b=e,I):b},I.padData=function(e){return arguments.length?(w=e,I):w},I.padDataOuter=function(e){return arguments.length?(E=e,I):E},I.clipEdge=function(e){return arguments.length?(S=e,I):S},I.clipVoronoi=function(e){return arguments.length?(x=e,I):x},I.useVoronoi=function(e){return arguments.length?(D=e,D===!1&&(x=!1),I):D},I.clipRadius=function(e){return arguments.length?(T=e,I):T},I.color=function(t){return arguments.length?(i=e.utils.getColor(t),I):i},I.shape=function(e){return arguments.length?(h=e,I):h},I.onlyCircles=function(e){return arguments.length?(p=e,I):p},I.id=function(e){return arguments.length?(s=e,I):s},I.singlePoint=function(e){return arguments.length?(M=e,I):M},I},e.models.scatterChart=function(){"use strict";function F(e){return e.each(function(e){function K(){if(T)return X.select(".nv-point-paths").style("pointer-events","all"),!1;X.select(".nv-point-paths").style("pointer-events","none");var i=d3.mouse(this);h.distortion(x).focus(i[0]),p.distortion(x).focus(i[1]),X.select(".nv-scatterWrap").call(t),b&&X.select(".nv-x.nv-axis").call(n),w&&X.select(".nv-y.nv-axis").call(r),X.select(".nv-distributionX").datum(e.filter(function(e){return!e.disabled})).call(o),X.select(".nv-distributionY").datum(e.filter(function(e){return!e.disabled})).call(u)}var C=d3.select(this),k=this,L=(f||parseInt(C.style("width"))||960)-a.left-a.right,I=(l||parseInt(C.style("height"))||400)-a.top-a.bottom;F.update=function(){C.transition().duration(D).call(F)},F.container=this,A.disabled=e.map(function(e){return!!e.disabled});if(!O){var q;O={};for(q in A)A[q]instanceof Array?O[q]=A[q].slice(0):O[q]=A[q]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var R=C.selectAll(".nv-noData").data([_]);return R.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),R.attr("x",a.left+L/2).attr("y",a.top+I/2).text(function(e){return e}),F}C.selectAll(".nv-noData").remove(),P=P||h,H=H||p;var U=C.selectAll("g.nv-wrap.nv-scatterChart").data([e]),z=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+t.id()),W=z.append("g"),X=U.select("g");W.append("rect").attr("class","nvd3 nv-background"),W.append("g").attr("class","nv-x nv-axis"),W.append("g").attr("class","nv-y nv-axis"),W.append("g").attr("class","nv-scatterWrap"),W.append("g").attr("class","nv-distWrap"),W.append("g").attr("class","nv-legendWrap"),W.append("g").attr("class","nv-controlsWrap");if(y){var V=S?L/2:L;i.width(V),U.select(".nv-legendWrap").datum(e).call(i),a.top!=i.height()&&(a.top=i.height(),I=(l||parseInt(C.style("height"))||400)-a.top-a.bottom),U.select(".nv-legendWrap").attr("transform","translate("+(L-V)+","+ -a.top+")")}S&&(s.width(180).color(["#444"]),X.select(".nv-controlsWrap").datum(j).attr("transform","translate(0,"+ -a.top+")").call(s)),U.attr("transform","translate("+a.left+","+a.top+")"),E&&X.select(".nv-y.nv-axis").attr("transform","translate("+L+",0)"),t.width(L).height(I).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),d!==0&&t.xDomain(null),v!==0&&t.yDomain(null),U.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t);if(d!==0){var $=h.domain()[1]-h.domain()[0];t.xDomain([h.domain()[0]-d*$,h.domain()[1]+d*$])}if(v!==0){var J=p.domain()[1]-p.domain()[0];t.yDomain([p.domain()[0]-v*J,p.domain()[1]+v*J])}(v!==0||d!==0)&&U.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),b&&(n.scale(h).ticks(n.ticks()&&n.ticks().length?n.ticks():L/100).tickSize(-I,0),X.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(n)),w&&(r.scale(p).ticks(r.ticks()&&r.ticks().length?r.ticks():I/36).tickSize(-L,0),X.select(".nv-y.nv-axis").call(r)),m&&(o.getData(t.x()).scale(h).width(L).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),W.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),X.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(e.filter(function(e){return!e.disabled})).call(o)),g&&(u.getData(t.y()).scale(p).width(I).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),W.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),X.select(".nv-distributionY").attr("transform","translate("+(E?L:-u.size())+",0)").datum(e.filter(function(e){return!e.disabled})).call(u)),d3.fisheye&&(X.select(".nv-background").attr("width",L).attr("height",I),X.select(".nv-background").on("mousemove",K),X.select(".nv-background").on("click",function(){T=!T}),t.dispatch.on("elementClick.freezeFisheye",function(){T=!T})),s.dispatch.on("legendClick",function(e,i){e.disabled=!e.disabled,x=e.disabled?0:2.5,X.select(".nv-background").style("pointer-events",e.disabled?"none":"all"),X.select(".nv-point-paths").style("pointer-events",e.disabled?"all":"none"),e.disabled?(h.distortion(x).focus(0),p.distortion(x).focus(0),X.select(".nv-scatterWrap").call(t),X.select(".nv-x.nv-axis").call(n),X.select(".nv-y.nv-axis").call(r)):T=!1,F.update()}),i.dispatch.on("stateChange",function(e){A.disabled=e.disabled,M.stateChange(A),F.update()}),t.dispatch.on("elementMouseover.tooltip",function(e){d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-distx-"+e.pointIndex).attr("y1",function(t,n){return e.pos[1]-I}),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-disty-"+e.pointIndex).attr("x2",e.pos[0]+o.size()),e.pos=[e.pos[0]+a.left,e.pos[1]+a.top],M.tooltipShow(e)}),M.on("tooltipShow",function(e){N&&B(e,k.parentNode)}),M.on("changeState",function(t){typeof t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),A.disabled=t.disabled),F.update()}),P=h.copy(),H=p.copy()}),F}var t=e.models.scatter(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o=e.models.distribution(),u=e.models.distribution(),a={top:30,right:20,bottom:50,left:75},f=null,l=null,c=e.utils.defaultColor(),h=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.xScale(),p=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.yScale(),d=0,v=0,m=!1,g=!1,y=!0,b=!0,w=!0,E=!1,S=!!d3.fisheye,x=0,T=!1,N=!0,C=function(e,t,n){return"<strong>"+t+"</strong>"},k=function(e,t,n){return"<strong>"+n+"</strong>"},L=null,A={},O=null,M=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),_="No Data Available.",D=250;t.xScale(h).yScale(p),n.orient("bottom").tickPadding(10),r.orient(E?"right":"left").tickPadding(10),o.axis("x"),u.axis("y"),s.updateState(!1);var P,H,B=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),f=i.pos[0]+(s.offsetLeft||0),l=p.range()[0]+a.top+(s.offsetTop||0),c=h.range()[0]+a.left+(s.offsetLeft||0),d=i.pos[1]+(s.offsetTop||0),v=n.tickFormat()(t.x()(i.point,i.pointIndex)),m=r.tickFormat()(t.y()(i.point,i.pointIndex));C!=null&&e.tooltip.show([f,l],C(i.series.key,v,m,i,F),"n",1,s,"x-nvtooltip"),k!=null&&e.tooltip.show([c,d],k(i.series.key,v,m,i,F),"e",1,s,"y-nvtooltip"),L!=null&&e.tooltip.show([o,u],L(i.series.key,v,m,i,F),i.value<0?"n":"s",null,s)},j=[{key:"Magnify",disabled:!0}];return t.dispatch.on("elementMouseout.tooltip",function(e){M.tooltipHide(e),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-distx-"+e.pointIndex).attr("y1",0),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-disty-"+e.pointIndex).attr("x2",u.size())}),M.on("tooltipHide",function(){N&&e.tooltip.cleanup()}),F.dispatch=M,F.scatter=t,F.legend=i,F.controls=s,F.xAxis=n,F.yAxis=r,F.distX=o,F.distY=u,d3.rebind(F,t,"id","interactive","pointActive","x","y","shape","size","xScale","yScale","zScale","xDomain","yDomain","xRange","yRange","sizeDomain","sizeRange","forceX","forceY","forceSize","clipVoronoi","clipRadius","useVoronoi"),F.options=e.utils.optionsFunc.bind(F),F.margin=function(e){return arguments.length?(a.top=typeof e.top!="undefined"?e.top:a.top,a.right=typeof e.right!="undefined"?e.right:a.right,a.bottom=typeof e.bottom!="undefined"?e.bottom:a.bottom,a.left=typeof e.left!="undefined"?e.left:a.left,F):a},F.width=function(e){return arguments.length?(f=e,F):f},F.height=function(e){return arguments.length?(l=e,F):l},F.color=function(t){return arguments.length?(c=e.utils.getColor(t),i.color(c),o.color(c),u.color(c),F):c},F.showDistX=function(e){return arguments.length?(m=e,F):m},F.showDistY=function(e){return arguments.length?(g=e,F):g},F.showControls=function(e){return arguments.length?(S=e,F):S},F.showLegend=function(e){return arguments.length?(y=e,F):y},F.showXAxis=function(e){return arguments.length?(b=e,F):b},F.showYAxis=function(e){return arguments.length?(w=e,F):w},F.rightAlignYAxis=function(e){return arguments.length?(E=e,r.orient(e?"right":"left"),F):E},F.fisheye=function(e){return arguments.length?(x=e,F):x},F.xPadding=function(e){return arguments.length?(d=e,F):d},F.yPadding=function(e){return arguments.length?(v=e,F):v},F.tooltips=function(e){return arguments.length?(N=e,F):N},F.tooltipContent=function(e){return arguments.length?(L=e,F):L},F.tooltipXContent=function(e){return arguments.length?(C=e,F):C},F.tooltipYContent=function(e){return arguments.length?(k=e,F):k},F.state=function(e){return arguments.length?(A=e,F):A},F.defaultState=function(e){return arguments.length?(O=e,F):O},F.noData=function(e){return arguments.length?(_=e,F):_},F.transitionDuration=function(e){return arguments.length?(D=e,F):D},F},e.models.scatterPlusLineChart=function(){"use strict";function B(e){return e.each(function(e){function $(){if(S)return z.select(".nv-point-paths").style("pointer-events","all"),!1;z.select(".nv-point-paths").style("pointer-events","none");var i=d3.mouse(this);h.distortion(E).focus(i[0]),p.distortion(E).focus(i[1]),z.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),g&&z.select(".nv-x.nv-axis").call(n),y&&z.select(".nv-y.nv-axis").call(r),z.select(".nv-distributionX").datum(e.filter(function(e){return!e.disabled})).call(o),z.select(".nv-distributionY").datum(e.filter(function(e){return!e.disabled})).call(u)}var T=d3.select(this),N=this,C=(f||parseInt(T.style("width"))||960)-a.left-a.right,j=(l||parseInt(T.style("height"))||400)-a.top-a.bottom;B.update=function(){T.transition().duration(M).call(B)},B.container=this,k.disabled=e.map(function(e){return!!e.disabled});if(!L){var F;L={};for(F in k)k[F]instanceof Array?L[F]=k[F].slice(0):L[F]=k[F]}if(!e||!e.length||!e.filter(function(e){return e.values.length}).length){var I=T.selectAll(".nv-noData").data([O]);return I.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),I.attr("x",a.left+C/2).attr("y",a.top+j/2).text(function(e){return e}),B}T.selectAll(".nv-noData").remove(),h=t.xScale(),p=t.yScale(),_=_||h,D=D||p;var q=T.selectAll("g.nv-wrap.nv-scatterChart").data([e]),R=q.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+t.id()),U=R.append("g"),z=q.select("g");U.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),U.append("g").attr("class","nv-x nv-axis"),U.append("g").attr("class","nv-y nv-axis"),U.append("g").attr("class","nv-scatterWrap"),U.append("g").attr("class","nv-regressionLinesWrap"),U.append("g").attr("class","nv-distWrap"),U.append("g").attr("class","nv-legendWrap"),U.append("g").attr("class","nv-controlsWrap"),q.attr("transform","translate("+a.left+","+a.top+")"),b&&z.select(".nv-y.nv-axis").attr("transform","translate("+C+",0)"),m&&(i.width(C/2),q.select(".nv-legendWrap").datum(e).call(i),a.top!=i.height()&&(a.top=i.height(),j=(l||parseInt(T.style("height"))||400)-a.top-a.bottom),q.select(".nv-legendWrap").attr("transform","translate("+C/2+","+ -a.top+")")),w&&(s.width(180).color(["#444"]),z.select(".nv-controlsWrap").datum(H).attr("transform","translate(0,"+ -a.top+")").call(s)),t.width(C).height(j).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),q.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),q.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+t.id()+")");var W=q.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(e){return e});W.enter().append("g").attr("class","nv-regLines");var X=W.selectAll(".nv-regLine").data(function(e){return[e]}),V=X.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0);X.transition().attr("x1",h.range()[0]).attr("x2",h.range()[1]).attr("y1",function(e,t){return p(h.domain()[0]*e.slope+e.intercept)}).attr("y2",function(e,t){return p(h.domain()[1]*e.slope+e.intercept)}).style("stroke",function(e,t,n){return c(e,n)}).style("stroke-opacity",function(e,t){return e.disabled||typeof e.slope=="undefined"||typeof e.intercept=="undefined"?0:1}),g&&(n.scale(h).ticks(n.ticks()?n.ticks():C/100).tickSize(-j,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(n)),y&&(r.scale(p).ticks(r.ticks()?r.ticks():j/36).tickSize(-C,0),z.select(".nv-y.nv-axis").call(r)),d&&(o.getData(t.x()).scale(h).width(C).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),U.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),z.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(e.filter(function(e){return!e.disabled})).call(o)),v&&(u.getData(t.y()).scale(p).width(
j).color(e.map(function(e,t){return e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),U.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),z.select(".nv-distributionY").attr("transform","translate("+(b?C:-u.size())+",0)").datum(e.filter(function(e){return!e.disabled})).call(u)),d3.fisheye&&(z.select(".nv-background").attr("width",C).attr("height",j),z.select(".nv-background").on("mousemove",$),z.select(".nv-background").on("click",function(){S=!S}),t.dispatch.on("elementClick.freezeFisheye",function(){S=!S})),s.dispatch.on("legendClick",function(e,i){e.disabled=!e.disabled,E=e.disabled?0:2.5,z.select(".nv-background").style("pointer-events",e.disabled?"none":"all"),z.select(".nv-point-paths").style("pointer-events",e.disabled?"all":"none"),e.disabled?(h.distortion(E).focus(0),p.distortion(E).focus(0),z.select(".nv-scatterWrap").call(t),z.select(".nv-x.nv-axis").call(n),z.select(".nv-y.nv-axis").call(r)):S=!1,B.update()}),i.dispatch.on("stateChange",function(e){k=e,A.stateChange(k),B.update()}),t.dispatch.on("elementMouseover.tooltip",function(e){d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-distx-"+e.pointIndex).attr("y1",e.pos[1]-j),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-disty-"+e.pointIndex).attr("x2",e.pos[0]+o.size()),e.pos=[e.pos[0]+a.left,e.pos[1]+a.top],A.tooltipShow(e)}),A.on("tooltipShow",function(e){x&&P(e,N.parentNode)}),A.on("changeState",function(t){typeof t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),k.disabled=t.disabled),B.update()}),_=h.copy(),D=p.copy()}),B}var t=e.models.scatter(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o=e.models.distribution(),u=e.models.distribution(),a={top:30,right:20,bottom:50,left:75},f=null,l=null,c=e.utils.defaultColor(),h=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.xScale(),p=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.yScale(),d=!1,v=!1,m=!0,g=!0,y=!0,b=!1,w=!!d3.fisheye,E=0,S=!1,x=!0,T=function(e,t,n){return"<strong>"+t+"</strong>"},N=function(e,t,n){return"<strong>"+n+"</strong>"},C=function(e,t,n,r){return"<h3>"+e+"</h3>"+"<p>"+r+"</p>"},k={},L=null,A=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),O="No Data Available.",M=250;t.xScale(h).yScale(p),n.orient("bottom").tickPadding(10),r.orient(b?"right":"left").tickPadding(10),o.axis("x"),u.axis("y"),s.updateState(!1);var _,D,P=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),f=i.pos[0]+(s.offsetLeft||0),l=p.range()[0]+a.top+(s.offsetTop||0),c=h.range()[0]+a.left+(s.offsetLeft||0),d=i.pos[1]+(s.offsetTop||0),v=n.tickFormat()(t.x()(i.point,i.pointIndex)),m=r.tickFormat()(t.y()(i.point,i.pointIndex));T!=null&&e.tooltip.show([f,l],T(i.series.key,v,m,i,B),"n",1,s,"x-nvtooltip"),N!=null&&e.tooltip.show([c,d],N(i.series.key,v,m,i,B),"e",1,s,"y-nvtooltip"),C!=null&&e.tooltip.show([o,u],C(i.series.key,v,m,i.point.tooltip,i,B),i.value<0?"n":"s",null,s)},H=[{key:"Magnify",disabled:!0}];return t.dispatch.on("elementMouseout.tooltip",function(e){A.tooltipHide(e),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-distx-"+e.pointIndex).attr("y1",0),d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+" .nv-disty-"+e.pointIndex).attr("x2",u.size())}),A.on("tooltipHide",function(){x&&e.tooltip.cleanup()}),B.dispatch=A,B.scatter=t,B.legend=i,B.controls=s,B.xAxis=n,B.yAxis=r,B.distX=o,B.distY=u,d3.rebind(B,t,"id","interactive","pointActive","x","y","shape","size","xScale","yScale","zScale","xDomain","yDomain","xRange","yRange","sizeDomain","sizeRange","forceX","forceY","forceSize","clipVoronoi","clipRadius","useVoronoi"),B.options=e.utils.optionsFunc.bind(B),B.margin=function(e){return arguments.length?(a.top=typeof e.top!="undefined"?e.top:a.top,a.right=typeof e.right!="undefined"?e.right:a.right,a.bottom=typeof e.bottom!="undefined"?e.bottom:a.bottom,a.left=typeof e.left!="undefined"?e.left:a.left,B):a},B.width=function(e){return arguments.length?(f=e,B):f},B.height=function(e){return arguments.length?(l=e,B):l},B.color=function(t){return arguments.length?(c=e.utils.getColor(t),i.color(c),o.color(c),u.color(c),B):c},B.showDistX=function(e){return arguments.length?(d=e,B):d},B.showDistY=function(e){return arguments.length?(v=e,B):v},B.showControls=function(e){return arguments.length?(w=e,B):w},B.showLegend=function(e){return arguments.length?(m=e,B):m},B.showXAxis=function(e){return arguments.length?(g=e,B):g},B.showYAxis=function(e){return arguments.length?(y=e,B):y},B.rightAlignYAxis=function(e){return arguments.length?(b=e,r.orient(e?"right":"left"),B):b},B.fisheye=function(e){return arguments.length?(E=e,B):E},B.tooltips=function(e){return arguments.length?(x=e,B):x},B.tooltipContent=function(e){return arguments.length?(C=e,B):C},B.tooltipXContent=function(e){return arguments.length?(T=e,B):T},B.tooltipYContent=function(e){return arguments.length?(N=e,B):N},B.state=function(e){return arguments.length?(k=e,B):k},B.defaultState=function(e){return arguments.length?(L=e,B):L},B.noData=function(e){return arguments.length?(O=e,B):O},B.transitionDuration=function(e){return arguments.length?(M=e,B):M},B},e.models.sparkline=function(){"use strict";function d(e){return e.each(function(e){var i=n-t.left-t.right,d=r-t.top-t.bottom,v=d3.select(this);s.domain(l||d3.extent(e,u)).range(h||[0,i]),o.domain(c||d3.extent(e,a)).range(p||[d,0]);var m=v.selectAll("g.nv-wrap.nv-sparkline").data([e]),g=m.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline"),b=g.append("g"),w=m.select("g");m.attr("transform","translate("+t.left+","+t.top+")");var E=m.selectAll("path").data(function(e){return[e]});E.enter().append("path"),E.exit().remove(),E.style("stroke",function(e,t){return e.color||f(e,t)}).attr("d",d3.svg.line().x(function(e,t){return s(u(e,t))}).y(function(e,t){return o(a(e,t))}));var S=m.selectAll("circle.nv-point").data(function(e){function n(t){if(t!=-1){var n=e[t];return n.pointIndex=t,n}return null}var t=e.map(function(e,t){return a(e,t)}),r=n(t.lastIndexOf(o.domain()[1])),i=n(t.indexOf(o.domain()[0])),s=n(t.length-1);return[i,r,s].filter(function(e){return e!=null})});S.enter().append("circle"),S.exit().remove(),S.attr("cx",function(e,t){return s(u(e,e.pointIndex))}).attr("cy",function(e,t){return o(a(e,e.pointIndex))}).attr("r",2).attr("class",function(e,t){return u(e,e.pointIndex)==s.domain()[1]?"nv-point nv-currentValue":a(e,e.pointIndex)==o.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),d}var t={top:2,right:0,bottom:2,left:0},n=400,r=32,i=!0,s=d3.scale.linear(),o=d3.scale.linear(),u=function(e){return e.x},a=function(e){return e.y},f=e.utils.getColor(["#000"]),l,c,h,p;return d.options=e.utils.optionsFunc.bind(d),d.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,d):t},d.width=function(e){return arguments.length?(n=e,d):n},d.height=function(e){return arguments.length?(r=e,d):r},d.x=function(e){return arguments.length?(u=d3.functor(e),d):u},d.y=function(e){return arguments.length?(a=d3.functor(e),d):a},d.xScale=function(e){return arguments.length?(s=e,d):s},d.yScale=function(e){return arguments.length?(o=e,d):o},d.xDomain=function(e){return arguments.length?(l=e,d):l},d.yDomain=function(e){return arguments.length?(c=e,d):c},d.xRange=function(e){return arguments.length?(h=e,d):h},d.yRange=function(e){return arguments.length?(p=e,d):p},d.animate=function(e){return arguments.length?(i=e,d):i},d.color=function(t){return arguments.length?(f=e.utils.getColor(t),d):f},d},e.models.sparklinePlus=function(){"use strict";function v(e){return e.each(function(c){function O(){if(a)return;var e=C.selectAll(".nv-hoverValue").data(u),r=e.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);e.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),e.attr("transform",function(e){return"translate("+s(t.x()(c[e],e))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1);if(!u.length)return;r.append("line").attr("x1",0).attr("y1",-n.top).attr("x2",0).attr("y2",b),r.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-n.top).attr("text-anchor","end").attr("dy",".9em"),C.select(".nv-hoverValue .nv-xValue").text(f(t.x()(c[u[0]],u[0]))),r.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-n.top).attr("text-anchor","start").attr("dy",".9em"),C.select(".nv-hoverValue .nv-yValue").text(l(t.y()(c[u[0]],u[0])))}function M(){function r(e,n){var r=Math.abs(t.x()(e[0],0)-n),i=0;for(var s=0;s<e.length;s++)Math.abs(t.x()(e[s],s)-n)<r&&(r=Math.abs(t.x()(e[s],s)-n),i=s);return i}if(a)return;var e=d3.mouse(this)[0]-n.left;u=[r(c,Math.round(s.invert(e)))],O()}var m=d3.select(this),g=(r||parseInt(m.style("width"))||960)-n.left-n.right,b=(i||parseInt(m.style("height"))||400)-n.top-n.bottom;v.update=function(){v(e)},v.container=this;if(!c||!c.length){var w=m.selectAll(".nv-noData").data([d]);return w.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),w.attr("x",n.left+g/2).attr("y",n.top+b/2).text(function(e){return e}),v}m.selectAll(".nv-noData").remove();var E=t.y()(c[c.length-1],c.length-1);s=t.xScale(),o=t.yScale();var S=m.selectAll("g.nv-wrap.nv-sparklineplus").data([c]),T=S.enter().append("g").attr("class","nvd3 nv-wrap nv-sparklineplus"),N=T.append("g"),C=S.select("g");N.append("g").attr("class","nv-sparklineWrap"),N.append("g").attr("class","nv-valueWrap"),N.append("g").attr("class","nv-hoverArea"),S.attr("transform","translate("+n.left+","+n.top+")");var k=C.select(".nv-sparklineWrap");t.width(g).height(b),k.call(t);var L=C.select(".nv-valueWrap"),A=L.selectAll(".nv-currentValue").data([E]);A.enter().append("text").attr("class","nv-currentValue").attr("dx",p?-8:8).attr("dy",".9em").style("text-anchor",p?"end":"start"),A.attr("x",g+(p?n.right:0)).attr("y",h?function(e){return o(e)}:0).style("fill",t.color()(c[c.length-1],c.length-1)).text(l(E)),N.select(".nv-hoverArea").append("rect").on("mousemove",M).on("click",function(){a=!a}).on("mouseout",function(){u=[],O()}),C.select(".nv-hoverArea rect").attr("transform",function(e){return"translate("+ -n.left+","+ -n.top+")"}).attr("width",g+n.left+n.right).attr("height",b+n.top)}),v}var t=e.models.sparkline(),n={top:15,right:100,bottom:10,left:50},r=null,i=null,s,o,u=[],a=!1,f=d3.format(",r"),l=d3.format(",.2f"),c=!0,h=!0,p=!1,d="No Data Available.";return v.sparkline=t,d3.rebind(v,t,"x","y","xScale","yScale","color"),v.options=e.utils.optionsFunc.bind(v),v.margin=function(e){return arguments.length?(n.top=typeof e.top!="undefined"?e.top:n.top,n.right=typeof e.right!="undefined"?e.right:n.right,n.bottom=typeof e.bottom!="undefined"?e.bottom:n.bottom,n.left=typeof e.left!="undefined"?e.left:n.left,v):n},v.width=function(e){return arguments.length?(r=e,v):r},v.height=function(e){return arguments.length?(i=e,v):i},v.xTickFormat=function(e){return arguments.length?(f=e,v):f},v.yTickFormat=function(e){return arguments.length?(l=e,v):l},v.showValue=function(e){return arguments.length?(c=e,v):c},v.alignValue=function(e){return arguments.length?(h=e,v):h},v.rightAlignValue=function(e){return arguments.length?(p=e,v):p},v.noData=function(e){return arguments.length?(d=e,v):d},v},e.models.stackedArea=function(){"use strict";function g(e){return e.each(function(e){var a=n-t.left-t.right,b=r-t.top-t.bottom,w=d3.select(this);p=v.xScale(),d=v.yScale();var E=e;e.forEach(function(e,t){e.seriesIndex=t,e.values=e.values.map(function(e,n){return e.index=n,e.seriesIndex=t,e})});var S=e.filter(function(e){return!e.disabled});e=d3.layout.stack().order(l).offset(f).values(function(e){return e.values}).x(o).y(u).out(function(e,t,n){var r=u(e)===0?0:n;e.display={y:r,y0:t}})(S);var T=w.selectAll("g.nv-wrap.nv-stackedarea").data([e]),N=T.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedarea"),C=N.append("defs"),k=N.append("g"),L=T.select("g");k.append("g").attr("class","nv-areaWrap"),k.append("g").attr("class","nv-scatterWrap"),T.attr("transform","translate("+t.left+","+t.top+")"),v.width(a).height(b).x(o).y(function(e){return e.display.y+e.display.y0}).forceY([0]).color(e.map(function(e,t){return e.color||i(e,e.seriesIndex)}));var A=L.select(".nv-scatterWrap").datum(e);A.call(v),C.append("clipPath").attr("id","nv-edge-clip-"+s).append("rect"),T.select("#nv-edge-clip-"+s+" rect").attr("width",a).attr("height",b),L.attr("clip-path",h?"url(#nv-edge-clip-"+s+")":"");var O=d3.svg.area().x(function(e,t){return p(o(e,t))}).y0(function(e){return d(e.display.y0)}).y1(function(e){return d(e.display.y+e.display.y0)}).interpolate(c),M=d3.svg.area().x(function(e,t){return p(o(e,t))}).y0(function(e){return d(e.display.y0)}).y1(function(e){return d(e.display.y0)}),_=L.select(".nv-areaWrap").selectAll("path.nv-area").data(function(e){return e});_.enter().append("path").attr("class",function(e,t){return"nv-area nv-area-"+t}).attr("d",function(e,t){return M(e.values,e.seriesIndex)}).on("mouseover",function(e,t){d3.select(this).classed("hover",!0),m.areaMouseover({point:e,series:e.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:e.seriesIndex})}).on("mouseout",function(e,t){d3.select(this).classed("hover",!1),m.areaMouseout({point:e,series:e.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:e.seriesIndex})}).on("click",function(e,t){d3.select(this).classed("hover",!1),m.areaClick({point:e,series:e.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:e.seriesIndex})}),_.exit().remove(),_.style("fill",function(e,t){return e.color||i(e,e.seriesIndex)}).style("stroke",function(e,t){return e.color||i(e,e.seriesIndex)}),_.transition().attr("d",function(e,t){return O(e.values,t)}),v.dispatch.on("elementMouseover.area",function(e){L.select(".nv-chart-"+s+" .nv-area-"+e.seriesIndex).classed("hover",!0)}),v.dispatch.on("elementMouseout.area",function(e){L.select(".nv-chart-"+s+" .nv-area-"+e.seriesIndex).classed("hover",!1)}),g.d3_stackedOffset_stackPercent=function(e){var t=e.length,n=e[0].length,r=1/t,i,s,o,a=[];for(s=0;s<n;++s){for(i=0,o=0;i<E.length;i++)o+=u(E[i].values[s]);if(o)for(i=0;i<t;i++)e[i][s][1]/=o;else for(i=0;i<t;i++)e[i][s][1]=r}for(s=0;s<n;++s)a[s]=0;return a}}),g}var t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=e.utils.defaultColor(),s=Math.floor(Math.random()*1e5),o=function(e){return e.x},u=function(e){return e.y},a="stack",f="zero",l="default",c="linear",h=!1,p,d,v=e.models.scatter(),m=d3.dispatch("tooltipShow","tooltipHide","areaClick","areaMouseover","areaMouseout");return v.size(2.2).sizeDomain([2.2,2.2]),v.dispatch.on("elementClick.area",function(e){m.areaClick(e)}),v.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],m.tooltipShow(e)}),v.dispatch.on("elementMouseout.tooltip",function(e){m.tooltipHide(e)}),g.dispatch=m,g.scatter=v,d3.rebind(g,v,"interactive","size","xScale","yScale","zScale","xDomain","yDomain","xRange","yRange","sizeDomain","forceX","forceY","forceSize","clipVoronoi","useVoronoi","clipRadius","highlightPoint","clearHighlights"),g.options=e.utils.optionsFunc.bind(g),g.x=function(e){return arguments.length?(o=d3.functor(e),g):o},g.y=function(e){return arguments.length?(u=d3.functor(e),g):u},g.margin=function(e){return arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof e.left!="undefined"?e.left:t.left,g):t},g.width=function(e){return arguments.length?(n=e,g):n},g.height=function(e){return arguments.length?(r=e,g):r},g.clipEdge=function(e){return arguments.length?(h=e,g):h},g.color=function(t){return arguments.length?(i=e.utils.getColor(t),g):i},g.offset=function(e){return arguments.length?(f=e,g):f},g.order=function(e){return arguments.length?(l=e,g):l},g.style=function(e){if(!arguments.length)return a;a=e;switch(a){case"stack":g.offset("zero"),g.order("default");break;case"stream":g.offset("wiggle"),g.order("inside-out");break;case"stream-center":g.offset("silhouette"),g.order("inside-out");break;case"expand":g.offset("expand"),g.order("default");break;case"stack_percent":g.offset(g.d3_stackedOffset_stackPercent),g.order("default")}return g},g.interpolate=function(e){return arguments.length?(c=e,g):c},g},e.models.stackedAreaChart=function(){"use strict";function M(y){return y.each(function(y){var _=d3.select(this),D=this,P=(a||parseInt(_.style("width"))||960)-u.left-u.right,H=(f||parseInt(_.style("height"))||400)-u.top-u.bottom;M.update=function(){_.transition().duration(A).call(M)},M.container=this,S.disabled=y.map(function(e){return!!e.disabled});if(!x){var B;x={};for(B in S)S[B]instanceof Array?x[B]=S[B].slice(0):x[B]=S[B]}if(!y||!y.length||!y.filter(function(e){return e.values.length}).length){var j=_.selectAll(".nv-noData").data([T]);return j.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),j.attr("x",u.left+P/2).attr("y",u.top+H/2).text(function(e){return e}),M}_.selectAll(".nv-noData").remove(),b=t.xScale(),w=t.yScale();var F=_.selectAll("g.nv-wrap.nv-stackedAreaChart").data([y]),I=F.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),q=F.select("g");I.append("rect").style("opacity",0),I.append("g").attr("class","nv-x nv-axis"),I.append("g").attr("class","nv-y nv-axis"),I.append("g").attr("class","nv-stackedWrap"),I.append("g").attr("class","nv-legendWrap"),I.append("g").attr("class","nv-controlsWrap"),I.append("g").attr("class","nv-interactive"),q.select("rect").attr("width",P).attr("height",H);if(h){var R=c?P-C:P;i.width(R),q.select(".nv-legendWrap").datum(y).call(i),u.top!=i.height()&&(u.top=i.height(),H=(f||parseInt(_.style("height"))||400)-u.top-u.bottom),q.select(".nv-legendWrap").attr("transform","translate("+(P-R)+","+ -u.top+")")}if(c){var U=[{key:L.stacked||"Stacked",metaKey:"Stacked",disabled:t.style()!="stack",style:"stack"},{key:L.stream||"Stream",metaKey:"Stream",disabled:t.style()!="stream",style:"stream"},{key:L.expanded||"Expanded",metaKey:"Expanded",disabled:t.style()!="expand",style:"expand"},{key:L.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:t.style()!="stack_percent",style:"stack_percent"}];C=k.length/3*260,U=U.filter(function(e){return k.indexOf(e.metaKey)!==-1}),s.width(C).color(["#444","#444","#444"]),q.select(".nv-controlsWrap").datum(U).call(s),u.top!=Math.max(s.height(),i.height())&&(u.top=Math.max(s.height(),i.height()),H=(f||parseInt(_.style("height"))||400)-u.top-u.bottom),q.select(".nv-controlsWrap").attr("transform","translate(0,"+ -u.top+")")}F.attr("transform","translate("+u.left+","+u.top+")"),v&&q.select(".nv-y.nv-axis").attr("transform","translate("+P+",0)"),m&&(o.width(P).height(H).margin({left:u.left,top:u.top}).svgContainer(_).xScale(b),F.select(".nv-interactive").call(o)),t.width(P).height(H);var z=q.select(".nv-stackedWrap").datum(y);z.transition().call(t),p&&(n.scale(b).ticks(P/100).tickSize(-H,0),q.select(".nv-x.nv-axis").attr("transform","translate(0,"+H+")"),q.select(".nv-x.nv-axis").transition().duration(0).call(n)),d&&(r.scale(w).ticks(t.offset()=="wiggle"?0:H/36).tickSize(-P,0).setTickFormat(t.style()=="expand"||t.style()=="stack_percent"?d3.format("%"):E),q.select(".nv-y.nv-axis").transition().duration(0).call(r)),t.dispatch.on("areaClick.toggle",function(e){y.filter(function(e){return!e.disabled}).length===1?y.forEach(function(e){e.disabled=!1}):y.forEach(function(t,n){t.disabled=n!=e.seriesIndex}),S.disabled=y.map(function(e){return!!e.disabled}),N.stateChange(S),M.update()}),i.dispatch.on("stateChange",function(e){S.disabled=e.disabled,N.stateChange(S),M.update()}),s.dispatch.on("legendClick",function(e,n){if(!e.disabled)return;U=U.map(function(e){return e.disabled=!0,e}),e.disabled=!1,t.style(e.style),S.style=t.style(),N.stateChange(S),M.update()}),o.dispatch.on("elementMousemove",function(i){t.clearHighlights();var s,a,f,c=[];y.filter(function(e,t){return e.seriesIndex=t,!e.disabled}).forEach(function(n,r){a=e.interactiveBisect(n.values,i.pointXValue,M.x()),t.highlightPoint(r,a,!0);var o=n.values[a];if(typeof o=="undefined")return;typeof s=="undefined"&&(s=o),typeof f=="undefined"&&(f=M.xScale()(M.x()(o,a)));var u=t.style()=="expand"?o.display.y:M.y()(o,a);c.push({key:n.key,value:u,color:l(n,n.seriesIndex),stackedValue:o.display})}),c.reverse();if(c.length>2){var h=M.yScale().invert(i.mouseY),p=Infinity,d=null;c.forEach(function(e,t){h=Math.abs(h);var n=Math.abs(e.stackedValue.y0),r=Math.abs(e.stackedValue.y);if(h>=n&&h<=r+n){d=t;return}}),d!=null&&(c[d].highlight=!0)}var v=n.tickFormat()(M.x()(s,a)),m=t.style()=="expand"?function(e,t){return d3.format(".1%")(e)}:function(e,t){return r.tickFormat()(e)};o.tooltip.position({left:f+u.left,top:i.mouseY+u.top}).chartContainer(D.parentNode).enabled(g).valueFormatter(m).data({value:v,series:c})(),o.renderGuideLine(f)}),o.dispatch.on("elementMouseout",function(e){N.tooltipHide(),t.clearHighlights()}),N.on("tooltipShow",function(e){g&&O(e,D.parentNode)}),N.on("changeState",function(e){typeof e.disabled!="undefined"&&y.length===e.disabled.length&&(y.forEach(function(t,n){t.disabled=e.disabled[n]}),S.disabled=e.disabled),typeof e.style!="undefined"&&t.style(e.style),M.update()})}),M}var t=e.models.stackedArea(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o=e.interactiveGuideline(),u={top:30,right:25,bottom:50,left:60},a=null,f=null,l=e.utils.defaultColor(),c=!0,h=!0,p=!0,d=!0,v=!1,m=!1,g=!0,y=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+" on "+t+"</p>"},b,w,E=d3.format(",.2f"),S={style:t.style()},x=null,T="No Data Available.",N=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),C=250,k=["Stacked","Stream","Expanded"],L={},A=250;n.orient("bottom").tickPadding(7),r.orient(v?"right":"left"),s.updateState(!1);var O=function(i,s){var o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=y(i.series.key,a,f,i,M);e.tooltip.show([o,u],l,i.value<0?"n":"s",null,s)};return t.dispatch.on("tooltipShow",function(e){e.pos=[e.pos[0]+u.left,e.pos[1]+u.top],N.tooltipShow(e)}),t.dispatch.on("tooltipHide",function(e){N.tooltipHide(e)}),N.on("tooltipHide",function(){g&&e.tooltip.cleanup()}),M.dispatch=N,M.stacked=t,M.legend=i,M.controls=s,M.xAxis=n,M.yAxis=r,M.interactiveLayer=o,d3.rebind(M,t,"x","y","size","xScale","yScale","xDomain","yDomain","xRange","yRange","sizeDomain","interactive","useVoronoi","offset","order","style","clipEdge","forceX","forceY","forceSize","interpolate"),M.options=e.utils.optionsFunc.bind(M),M.margin=function(e){return arguments.length?(u.top=typeof e.top!="undefined"?e.top:u.top,u.right=typeof e.right!="undefined"?e.right:u.right,u.bottom=typeof e.bottom!="undefined"?e.bottom:u.bottom,u.left=typeof e.left!="undefined"?e.left:u.left,M):u},M.width=function(e){return arguments.length?(a=e,M):a},M.height=function(e){return arguments.length?(f=e,M):f},M.color=function(n){return arguments.length?(l=e.utils.getColor(n),i.color(l),t.color(l),M):l},M.showControls=function(e){return arguments.length?(c=e,M):c},M.showLegend=function(e){return arguments.length?(h=e,M):h},M.showXAxis=function(e){return arguments.length?(p=e,M):p},M.showYAxis=function(e){return arguments.length?(d=e,M):d},M.rightAlignYAxis=function(e){return arguments.length?(v=e,r.orient(e?"right":"left"),M):v},M.useInteractiveGuideline=function(e){return arguments.length?(m=e,e===!0&&(M.interactive(!1),M.useVoronoi(!1)),M):m},M.tooltip=function(e){return arguments.length?(y=e,M):y},M.tooltips=function(e){return arguments.length?(g=e,M):g},M.tooltipContent=function(e){return arguments.length?(y=e,M):y},M.state=function(e){return arguments.length?(S=e,M):S},M.defaultState=function(e){return arguments.length?(x=e,M):x},M.noData=function(e){return arguments.length?(T=e,M):T},M.transitionDuration=function(e){return arguments.length?(A=e,M):A},M.controlsData=function(e){return arguments.length?(k=e,M):k},M.controlLabels=function(e){return arguments.length?typeof e!="object"?L:(L=e,M):L},r.setTickFormat=r.tickFormat,r.tickFormat=function(e){return arguments.length?(E=e,r):E},M}})();
\ No newline at end of file
https://bitbucket.org/galaxy/galaxy-central/commits/ed3e84645aa2/
Changeset: ed3e84645aa2
User: guerler
Date: 2014-01-16 06:43:19
Summary: Merge
Affected #: 12 files
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -1779,6 +1779,7 @@
visible = hda.visible,
state = hda.state,
file_size = int( hda.get_size() ),
+ update_time = hda.update_time.isoformat(),
data_type = hda.ext,
genome_build = hda.dbkey,
misc_info = hda.info,
@@ -2217,6 +2218,7 @@
library_dataset_id = ldda.library_dataset_id,
file_size = file_size,
file_name = ldda.file_name,
+ update_time = ldda.update_time.isoformat(),
data_type = ldda.ext,
genome_build = ldda.dbkey,
misc_info = ldda.info,
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 lib/galaxy/webapps/galaxy/api/lda_datasets.py
--- a/lib/galaxy/webapps/galaxy/api/lda_datasets.py
+++ b/lib/galaxy/webapps/galaxy/api/lda_datasets.py
@@ -14,9 +14,9 @@
import urllib2
import zipfile
from paste.httpexceptions import HTTPBadRequest
+from galaxy import util, web
from galaxy.exceptions import ItemAccessibilityException, MessageException, ItemDeletionException, ObjectNotFound
from galaxy.security import Action
-from galaxy import util, web
from galaxy.util.streamball import StreamBall
from galaxy.web.base.controller import BaseAPIController, UsesVisualizationMixin
@@ -39,14 +39,12 @@
:returns: detailed dataset information from base controller
.. seealso:: :attr:`galaxy.web.base.controller.UsesLibraryMixinItems.get_library_dataset`
"""
- # Get dataset.
try:
dataset = self.get_library_dataset( trans, id = id, check_ownership=False, check_accessible=True )
except Exception, e:
trans.response.status = 500
return str( e )
try:
- # Default: return dataset as dict.
rval = dataset.to_dict()
except Exception, e:
rval = "Error in dataset API at listing contents: " + str( e )
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 lib/galaxy/webapps/tool_shed/controllers/repository.py
--- a/lib/galaxy/webapps/tool_shed/controllers/repository.py
+++ b/lib/galaxy/webapps/tool_shed/controllers/repository.py
@@ -971,8 +971,9 @@
@web.require_login( "deprecate repository" )
def deprecate( self, trans, **kwd ):
"""Mark a repository in the tool shed as deprecated or not deprecated."""
- # Marking a repository in the tool shed as deprecated has no effect on any downloadable changeset revisions that may be associated with the
- # repository. Revisions are not marked as not downlaodable because those that have installed the repository must be allowed to get updates.
+ # Marking a repository in the tool shed as deprecated has no effect on any downloadable changeset
+ # revisions that may be associated with the repository. Revisions are not marked as not downlaodable
+ # because those that have installed the repository must be allowed to get updates.
message = kwd.get( 'message', '' )
status = kwd.get( 'status', 'done' )
repository_id = kwd.get( 'id', None )
@@ -2287,7 +2288,9 @@
status = 'warning'
else:
# Handle messaging for orphan tool dependency definitions.
- orphan_message = tool_dependency_util.generate_message_for_orphan_tool_dependencies( trans, repository, metadata )
+ orphan_message = tool_dependency_util.generate_message_for_orphan_tool_dependencies( trans,
+ repository,
+ metadata )
if orphan_message:
message += orphan_message
status = 'warning'
@@ -2302,14 +2305,23 @@
skip_tool_tests_check_box = CheckboxField( 'skip_tool_tests', checked=skip_tool_tests_checked )
categories = suc.get_categories( trans )
selected_categories = [ rca.category_id for rca in repository.categories ]
- containers_dict = container_util.build_repository_containers_for_tool_shed( trans, repository, changeset_revision, repository_dependencies, repository_metadata )
+ containers_dict = container_util.build_repository_containers_for_tool_shed( trans,
+ repository,
+ changeset_revision,
+ repository_dependencies,
+ repository_metadata )
heads = suc.get_repository_heads( repo )
+ deprecated_repository_dependency_tups = \
+ repository_dependency_util.get_repository_dependency_tups_from_repository_metadata( trans.app,
+ repository_metadata,
+ deprecated_only=True )
return trans.fill_template( '/webapps/tool_shed/repository/manage_repository.mako',
repo_name=repo_name,
description=description,
long_description=long_description,
current_allow_push_list=current_allow_push_list,
allow_push_select_field=allow_push_select_field,
+ deprecated_repository_dependency_tups=deprecated_repository_dependency_tups,
repo=repo,
heads=heads,
repository=repository,
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 lib/tool_shed/galaxy_install/installed_repository_manager.py
--- a/lib/tool_shed/galaxy_install/installed_repository_manager.py
+++ b/lib/tool_shed/galaxy_install/installed_repository_manager.py
@@ -76,7 +76,7 @@
# Get the list of repository dependencies for this repository.
status = self.install_model.ToolShedRepository.installation_status.INSTALLED
repository_dependency_tups = \
- repository_dependency_util.get_repository_dependency_tups_for_repository( self.app, repository, status=status )
+ repository_dependency_util.get_repository_dependency_tups_for_installed_repository( self.app, repository, status=status )
# Add an entry to self.installed_repository_dependencies_of_installed_repositories.
if repository_tup not in self.installed_repository_dependencies_of_installed_repositories:
debug_msg = "Adding an entry for revision %s of repository %s owned by %s " % ( installed_changeset_revision, name, owner )
@@ -132,7 +132,7 @@
debug_msg += "to repository_dependencies_of_installed_repositories."
log.debug( debug_msg )
repository_dependency_tups = \
- repository_dependency_util.get_repository_dependency_tups_for_repository( self.app, repository, status=None )
+ repository_dependency_util.get_repository_dependency_tups_for_installed_repository( self.app, repository, status=None )
self.repository_dependencies_of_installed_repositories[ repository_tup ] = repository_dependency_tups
def add_entry_to_runtime_tool_dependencies_of_installed_tool_dependencies( self, tool_dependency ):
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 lib/tool_shed/util/repository_dependency_util.py
--- a/lib/tool_shed/util/repository_dependency_util.py
+++ b/lib/tool_shed/util/repository_dependency_util.py
@@ -303,10 +303,13 @@
key_rd_dicts_to_be_processed=None, all_repository_dependencies=None,
handled_key_rd_dicts=None, circular_repository_dependencies=None ):
"""
- Return a dictionary of all repositories upon which the contents of the received repository_metadata record depend. The dictionary keys
- are name-spaced values consisting of toolshed_base_url/repository_name/repository_owner/changeset_revision and the values are lists of
- repository_dependency tuples consisting of ( toolshed_base_url, repository_name, repository_owner, changeset_revision ). This method
- ensures that all required repositories to the nth degree are returned.
+ Return a dictionary of all repositories upon which the contents of the received
+ repository_metadata record depend. The dictionary keys are name-spaced values
+ consisting of:
+ toolshed_base_url/repository_name/repository_owner/changeset_revision
+ and the values are lists of repository_dependency tuples consisting of:
+ ( toolshed_base_url, repository_name, repository_owner, changeset_revision ).
+ This method ensures that all required repositories to the nth degree are returned.
"""
if handled_key_rd_dicts is None:
handled_key_rd_dicts = []
@@ -331,8 +334,8 @@
all_repository_dependencies = initialize_all_repository_dependencies( current_repository_key,
repository_dependencies_dict,
all_repository_dependencies )
- # Handle the repository dependencies defined in the current repository, if any, and populate the various repository dependency objects for
- # this round of processing.
+ # Handle the repository dependencies defined in the current repository, if any, and populate
+ # the various repository dependency objects for this round of processing.
current_repository_key_rd_dicts, key_rd_dicts_to_be_processed, handled_key_rd_dicts, all_repository_dependencies = \
populate_repository_dependency_objects_for_processing( trans,
current_repository_key,
@@ -375,10 +378,41 @@
all_repository_dependencies = prune_invalid_repository_dependencies( all_repository_dependencies )
return all_repository_dependencies
-def get_repository_dependency_tups_for_repository( app, repository, dependency_tups=None, status=None ):
+def get_repository_dependency_tups_from_repository_metadata( app, repository_metadata, deprecated_only=False ):
+ """
+ Return a list of of tuples defining repository objects required by the received repository. The returned
+ list defines the entire repository dependency tree. This method is called only from the Tool Shed.
+ """
+ dependency_tups = []
+ if repository_metadata is not None:
+ metadata = repository_metadata.metadata
+ if metadata:
+ repository_dependencies_dict = metadata.get( 'repository_dependencies', None )
+ if repository_dependencies_dict is not None:
+ repository_dependency_tups = repository_dependencies_dict.get( 'repository_dependencies', None )
+ if repository_dependency_tups is not None:
+ # The value of repository_dependency_tups is a list of repository dependency tuples like this:
+ # ['http://localhost:9009', 'package_samtools_0_1_18', 'devteam', 'ef37fc635cb9', 'False', 'False']
+ for repository_dependency_tup in repository_dependency_tups:
+ toolshed, name, owner, changeset_revision, pir, oicct = \
+ common_util.parse_repository_dependency_tuple( repository_dependency_tup )
+ repository = suc.get_repository_by_name_and_owner( app, name, owner )
+ if repository:
+ if deprecated_only:
+ if repository.deprecated:
+ dependency_tups.append( repository_dependency_tup )
+ else:
+ dependency_tups.append( repository_dependency_tup )
+ else:
+ log.debug( "Cannot locate repository %s owned by %s for inclusion in repository dependency tups." % \
+ ( name, owner ) )
+ return dependency_tups
+
+def get_repository_dependency_tups_for_installed_repository( app, repository, dependency_tups=None, status=None ):
"""
Return a list of of tuples defining tool_shed_repository objects (whose status can be anything) required by the
- received repository. The returned list defines the entire repository dependency tree.
+ received repository. The returned list defines the entire repository dependency tree. This method is called
+ only from Galaxy.
"""
if dependency_tups is None:
dependency_tups = []
@@ -393,7 +427,9 @@
continue
if required_repository_tup not in dependency_tups:
dependency_tups.append( required_repository_tup )
- return get_repository_dependency_tups_for_repository( app, required_repository, dependency_tups=dependency_tups )
+ return get_repository_dependency_tups_for_installed_repository( app,
+ required_repository,
+ dependency_tups=dependency_tups )
return dependency_tups
def get_repository_tuple_for_installed_repository_manager( repository ):
@@ -657,12 +693,16 @@
containers_dict[ 'missing_repository_dependencies' ] = None
return containers_dict
-def populate_repository_dependency_objects_for_processing( trans, current_repository_key, repository_dependencies_dict, key_rd_dicts_to_be_processed,
- handled_key_rd_dicts, circular_repository_dependencies, all_repository_dependencies ):
+def populate_repository_dependency_objects_for_processing( trans, current_repository_key, repository_dependencies_dict,
+ key_rd_dicts_to_be_processed, handled_key_rd_dicts,
+ circular_repository_dependencies, all_repository_dependencies ):
"""
- The process that discovers all repository dependencies for a specified repository's changeset revision uses this method to populate the following items
- for the current processing loop: filtered_current_repository_key_rd_dicts, key_rd_dicts_to_be_processed, handled_key_rd_dicts, all_repository_dependencies.
- Each processing loop may discover more repository dependencies, so this method is repeatedly called until all repository dependencies have been discovered.
+ The process that discovers all repository dependencies for a specified repository's
+ changeset revision uses this method to populate the following items for the current
+ processing loop: filtered_current_repository_key_rd_dicts, key_rd_dicts_to_be_processed,
+ handled_key_rd_dicts, all_repository_dependencies. Each processing loop may discover
+ more repository dependencies, so this method is repeatedly called until all repository
+ dependencies have been discovered.
"""
current_repository_key_rd_dicts = []
filtered_current_repository_key_rd_dicts = []
@@ -673,13 +713,15 @@
if current_repository_key_rd_dicts and current_repository_key:
# Remove all repository dependencies that point to a revision within its own repository.
current_repository_key_rd_dicts = remove_ropository_dependency_reference_to_self( current_repository_key_rd_dicts )
- current_repository_key_rd_dicts = get_updated_changeset_revisions_for_repository_dependencies( trans, current_repository_key_rd_dicts )
+ current_repository_key_rd_dicts = get_updated_changeset_revisions_for_repository_dependencies( trans,
+ current_repository_key_rd_dicts )
for key_rd_dict in current_repository_key_rd_dicts:
# Filter out repository dependencies that are required only if compiling the dependent repository's tool dependency.
key_rd_dict = filter_only_if_compiling_contained_td( key_rd_dict )
if key_rd_dict:
is_circular = False
- if not in_key_rd_dicts( key_rd_dict, handled_key_rd_dicts ) and not in_key_rd_dicts( key_rd_dict, key_rd_dicts_to_be_processed ):
+ if not in_key_rd_dicts( key_rd_dict, handled_key_rd_dicts ) and not in_key_rd_dicts( key_rd_dict,
+ key_rd_dicts_to_be_processed ):
filtered_current_repository_key_rd_dicts.append( key_rd_dict )
repository_dependency = key_rd_dict[ current_repository_key ]
if current_repository_key in all_repository_dependencies:
@@ -708,8 +750,10 @@
def prune_invalid_repository_dependencies( repository_dependencies ):
"""
- Eliminate all invalid entries in the received repository_dependencies dictionary. An entry is invalid if the value_list of the key/value pair is
- empty. This occurs when an invalid combination of tool shed, name , owner, changeset_revision is used and a repository_metadata record is not found.
+ Eliminate all invalid entries in the received repository_dependencies dictionary. An entry
+ is invalid if the value_list of the key/value pair is empty. This occurs when an invalid
+ combination of tool shed, name , owner, changeset_revision is used and a repository_metadata
+ record is not found.
"""
valid_repository_dependencies = {}
description = repository_dependencies.get( 'description', None )
@@ -752,7 +796,9 @@
toolshed, name, owner, changeset_revision, prior_installation_required, only_if_compiling_contained_td = \
common_util.parse_repository_dependency_tuple( repository_dependency )
if rd_toolshed == toolshed and rd_name == name and rd_owner == owner:
- log.debug( "Removing repository dependency for repository %s owned by %s since it refers to a revision within itself." % ( name, owner ) )
+ debug_msg = "Removing repository dependency for repository %s owned by %s " % ( name, owner )
+ debug_msg += 'since it refers to a revision within itself.'
+ log.debug( debug_msg )
else:
new_key_rd_dict = {}
new_key_rd_dict[ key ] = repository_dependency
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 static/scripts/galaxy.library.js
--- a/static/scripts/galaxy.library.js
+++ b/static/scripts/galaxy.library.js
@@ -122,7 +122,7 @@
// CONTAINER
tmpl_array.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');
- tmpl_array.push('<h3>New Data Libraries. This is work in progress. Report problems & ideas to <a href="mailto:marten@bx.psu.edu?Subject=DataLibraries_Feedback" target="_blank">Marten</a>.</h3>');
+ tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
// TOOLBAR
tmpl_array.push('<div id="library_folder_toolbar" >');
@@ -457,6 +457,7 @@
var self = this;
this.modal = new mod_modal.GalaxyModal({
destructible : true,
+ bindClosingEvents: true,
title : 'Dataset Details',
body : template,
buttons : {
@@ -477,7 +478,6 @@
$(this.modal.elMain).find('#dataset_import_single').val(self.lastSelectedHistory);
}
}
- this.modal.bindEvents();
this.modal.show();
},
@@ -614,6 +614,7 @@
var history_modal_tmpl = _.template(self.templateBulkImportInModal(), {histories : histories.models});
self.modal = new mod_modal.GalaxyModal({
destructible : true,
+ bindClosingEvents: true,
title : 'Import into History',
body : history_modal_tmpl,
buttons : {
@@ -621,7 +622,6 @@
'Close' : function() {self.modal.hideOrDestroy();}
}
});
- self.modal.bindEvents();
self.modal.show();
},
error: function(){
@@ -724,6 +724,7 @@
//send request
$('<form action="'+ url +'" method="'+ (method||'post') +'">'+inputs+'</form>')
.appendTo('body').submit().remove();
+
mod_toastr.info('Your download will begin soon');
};
},
@@ -737,6 +738,7 @@
var self = this;
this.modal = new mod_modal.GalaxyModal({
destructible : true,
+ bindClosingEvents: true,
title : 'Create New Folder',
body : this.templateNewFolderInModal(),
buttons : {
@@ -744,7 +746,6 @@
'Close' : function() {self.modal.hideOrDestroy(); self.modal = null;}
}
});
- this.modal.bindEvents();
this.modal.show();
},
@@ -810,7 +811,7 @@
tmpl_array = [];
tmpl_array.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; overflow: auto !important; ">');
tmpl_array.push('');
- tmpl_array.push('<h3>New Data Libraries. This is work in progress. Report problems & ideas to <a href="mailto:marten@bx.psu.edu?Subject=DataLibraries_Feedback" target="_blank">Marten</a>.</h3>');
+ tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
tmpl_array.push('<a href="" id="create_new_library_btn" class="btn btn-primary file ">New Library</a>');
tmpl_array.push('<table class="table table-condensed">');
tmpl_array.push(' <thead>');
@@ -866,7 +867,7 @@
},
error: function(model, response){
if (response.statusCode().status === 403){
- mod_toastr.error('Please log in first. Redirecting to login page in 3s.');
+ mod_toastr.info('Please log in first. Redirecting to login page in 3s.');
setTimeout(that.redirectToLogin, 3000);
} else {
mod_toastr.error('An error occured. Please try again.');
@@ -894,6 +895,7 @@
var self = this;
this.modal = new mod_modal.GalaxyModal({
destructible : true,
+ bindClosingEvents: true,
title : 'Create New Library',
body : this.templateNewLibraryInModal(),
buttons : {
@@ -901,7 +903,6 @@
'Close' : function() {self.modal.hideOrDestroy();}
}
});
- this.modal.bindEvents();
this.modal.show();
},
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 static/scripts/galaxy.modal.js
--- a/static/scripts/galaxy.modal.js
+++ b/static/scripts/galaxy.modal.js
@@ -16,50 +16,72 @@
height : null,
width : null
},
+
+ // flag whether the closing events are bound
+ eventsBound: false,
// options
options : {
// by default the modal cannot be removed by the self.destroy() method
// but only hidden through self.hide()
- destructible: false
+ destructible: false,
+ // by default don't bind the events
+ bindClosingEvents: false
},
// initialize
initialize : function(options) {
self = this;
- if (options)
+ if (options){
this.create(options);
+ }
},
hideOrDestroy: function(){
- if (this.options.destructible){
- self.destroy();
+ self.visible = false;
+
+ //unbinds event for ALL modals?
+ self.unbindEvents();
+
+ if (self.options.destructible){
+ self.$el.remove(); // destroy
} else {
self.hide();
}
},
+ // hide modal, shouldn't be called directly but through hideOrDestroy()
+ // however hide() remains for backwards compatibility
+ hide: function(){
+ this.visible = false;
+ this.$el.fadeOut('fast');
+ },
+
// bind the click-to-hide function
bindEvents: function() {
// bind the ESC key to hideOrDestroy() function
$(document).on('keyup', function(event){
- if (event.keyCode == 27) { self.hideOrDestroy() }
+ if (event.keyCode == 27) {
+ self.hideOrDestroy()
+ }
})
// bind the 'click anywhere' to hideOrDestroy() function...
- $('html').on('click', function(event){
- self.hideOrDestroy()
- })
+ $('html').on('click', self.hideOrDestroy)
// ...but don't hide if the click is on modal content
$('.modal-content').on('click', function(event){
event.stopPropagation();
})
+
+ self.eventsBound = true;
},
// unbind the click-to-hide function
unbindEvents: function(){
// unbind the ESC key to hideOrDestroy() function
$(document).off('keyup', function(event){
- if (event.keyCode == 27) { self.hideOrDestroy() }
+ if (event.keyCode == 27) {
+ self.hideOrDestroy()
+ }
})
// unbind the 'click anywhere' to hideOrDestroy() function...
$('html').off('click', function(event){
@@ -68,6 +90,8 @@
$('.modal-content').off('click', function(event){
event.stopPropagation();
})
+
+ self.eventsBound = false;
},
// adds and displays a new frame/window
@@ -76,59 +100,43 @@
this.initialize(options);
// fix height
- if (this.options.height)
- {
+ if (this.options.height){
this.$body.css('height', this.options.height);
this.$body.css('overflow', 'hidden');
- } else
+ } else{
this.$body.css('max-height', $(window).height() / 2);
+ }
// fix width
- if (this.options.width)
+ if (this.options.width){
this.$dialog.css('width', this.options.width);
+ }
// show
- if (this.visible)
+ if (this.visible){
this.$el.show();
- else
+ } else {
this.$el.fadeIn('fast');
+ }
// set flag
this.visible = true;
},
- // hide modal, shouldn't be called directly but through hideOrDestroy()
- hide: function(){
- // fade out
- this.$el.fadeOut('fast');
- // set flag
- this.visible = false;
- // unbind events
- this.unbindEvents();
- },
-
- // destroy modal, shouldn't be called directly but through hideOrDestroy()
- destroy: function(){
- // set flag
- this.visible = false;
- // unbind events
- this.unbindEvents();
- // remove
- this.$el.remove();
- },
-
// create
create: function(options) {
// configure options
this.options = _.defaults(options, this.optionsDefault);
// check for progress bar request
- if (this.options.body == 'progress')
+ if (this.options.body == 'progress'){
this.options.body = $('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>');
+ }
// remove former element
- if (this.$el)
+ if (this.$el){
this.$el.remove();
+ }
// create new element
this.setElement(this.template(this.options.title));
@@ -144,8 +152,9 @@
this.$body.html(this.options.body);
// configure background
- if (!this.options.backdrop)
+ if (!this.options.backdrop){
this.$backdrop.removeClass('in');
+ }
// append buttons
if (this.options.buttons) {
@@ -160,6 +169,10 @@
// append to main element
$(this.elMain).append($(this.el));
+
+ if (this.options.bindClosingEvents && !this.eventsBound){
+ this.bindEvents();
+ }
},
// enable buttons
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 static/scripts/packed/galaxy.library.js
--- a/static/scripts/packed/galaxy.library.js
+++ b/static/scripts/packed/galaxy.library.js
@@ -1,1 +1,1 @@
-var view=null;var library_router=null;var responses=[];define(["galaxy.modal","galaxy.masthead","utils/galaxy.utils","libs/toastr"],function(k,l,h,n){var f=Backbone.Model.extend({urlRoot:"/api/libraries"});var c=Backbone.Model.extend({urlRoot:"/api/folders"});var o=Backbone.Collection.extend({url:"/api/libraries",model:f});var i=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var d=Backbone.Collection.extend({model:i});var e=Backbone.Model.extend({defaults:{folder:new d(),full_path:"unknown",urlRoot:"/api/folders/",id:"unknown"},parse:function(r){this.full_path=r[0].full_path;this.get("folder").reset(r[1].folder_contents);return r}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var j=Backbone.Model.extend({url:"/api/histories/"});var p=Backbone.Collection.extend({url:"/api/histories",model:j});var q=Backbone.Router.extend({routes:{"":"libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var m=Backbone.View.extend({el:"#center",progress:0,progressStep:1,lastSelectedHistory:"",modal:null,folders:null,initialize:function(){this.folders=[];this.queue=jQuery.Deferred();this.queue.resolve()},templateFolder:function(){var r=[];r.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');r.push('<h3>New Data Libraries. This is work in progress. Report problems & ideas to <a href="mailto:marten@bx.psu.edu?Subject=DataLibraries_Feedback" target="_blank">Marten</a>.</h3>');r.push('<div id="library_folder_toolbar" >');r.push(' <button title="Create New Folder" id="toolbtn_create_folder" class="btn btn-primary" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');r.push(' <button id="toolbtn_bulk_import" class="btn btn-primary" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-external-link"></span> to history</button>');r.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');r.push(' <button id="drop_toggle" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">');r.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');r.push(" </button>");r.push(' <ul class="dropdown-menu" role="menu">');r.push(' <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');r.push(" </ul>");r.push(" </div>");r.push("</div>");r.push('<div class="library_breadcrumb">');r.push('<a title="Return to the list of libraries" href="#">Libraries</a><b>|</b> ');r.push("<% _.each(path, function(path_item) { %>");r.push("<% if (path_item[0] != id) { %>");r.push('<a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a><b>|</b> ');r.push("<% } else { %>");r.push('<span title="You are in this folder"><%- path_item[1] %></span>');r.push("<% } %>");r.push("<% }); %>");r.push("</div>");r.push('<table id="folder_table" class="table table-condensed">');r.push(" <thead>");r.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');r.push(' <th class="button_heading">view</th>');r.push(" <th>name</th>");r.push(" <th>data type</th>");r.push(" <th>size</th>");r.push(" <th>date (UTC)</th>");r.push(" </thead>");r.push(" <tbody>");r.push(" <td></td>");r.push(' <td><button title="Go to parent folder" type="button" data-id="<%- upper_folder_id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-arrow-up"></span> .. go up</td>');r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" </tr>");r.push(" <% _.each(items, function(content_item) { %>");r.push(' <tr class="folder_row light" id="<%- content_item.id %>">');r.push(' <% if (content_item.get("type") === "folder") { %>');r.push(" <td></td>");r.push(' <td><button title="Open this folder" type="button" data-id="<%- content_item.id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-folder-open"></span> browse</td>');r.push(' <td><%- content_item.get("name") %>');r.push(' <% if (content_item.get("item_count") === 0) { %>');r.push(' <span class="muted">(empty folder)</span>');r.push(" <% } %>");r.push(" </td>");r.push(" <td>folder</td>");r.push(' <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>');r.push(" <% } else { %>");r.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');r.push(" <td>");r.push(' <button title="See details of this dataset" type="button" class="library-dataset btn btn-default btn-xs">');r.push(' <span class="fa fa-eye"></span> details');r.push(" </button>");r.push(" </td>");r.push(' <td><%- content_item.get("name") %></td>');r.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');r.push(' <td><%= _.escape(content_item.get("readable_size")) %></td>');r.push(" <% } %> ");r.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>');r.push(" </tr>");r.push(" <% }); %>");r.push(" ");r.push(" </tbody>");r.push("</table>");r.push("</div>");return r.join("")},templateDatasetModal:function(){var r=[];r.push('<div id="dataset_info_modal">');r.push(' <table class="table table-striped table-condensed">');r.push(" <tr>");r.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');r.push(' <td><%= _.escape(item.get("name")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Data type</th>');r.push(' <td><%= _.escape(item.get("data_type")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Genome build</th>');r.push(' <td><%= _.escape(item.get("genome_build")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Size</th>');r.push(" <td><%= _.escape(size) %></td>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Date uploaded (UTC)</th>');r.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Uploaded by</th>');r.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');r.push(" </tr>");r.push(' <tr scope="row">');r.push(' <th scope="row">Data Lines</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Comment Lines</th>');r.push(' <% if (item.get("metadata_comment_lines") === "") { %>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');r.push(" <% } else { %>");r.push(' <td scope="row">unknown</td>');r.push(" <% } %>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Number of Columns</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Column Types</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Miscellaneous information</th>');r.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');r.push(" </tr>");r.push(" </table>");r.push(' <pre class="peek">');r.push(" </pre>");r.push("</div>");return r.join("")},templateHistorySelectInModal:function(){var r=[];r.push('<span id="history_modal_combo" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateBulkImportInModal:function(){var r=[];r.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateProgressBar:function(){var r=[];r.push('<div class="import_text">');r.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");r.push("</div>");r.push('<div class="progress">');r.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');r.push(' <span class="completion_span">0% Complete</span>');r.push(" </div>");r.push("</div>");r.push("");return r.join("")},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return tmpl_array.join("")},events:{"click #select-all-checkboxes":"selectAll","click .folder_row":"selectClickedRow","click #toolbtn_bulk_import":"modalBulkImport","click #toolbtn_dl":"bulkDownload","click .library-dataset":"showDatasetDetails","click #toolbtn_create_folder":"createFolderFromModal","click .btn_open_folder":"navigateToFolder"},render:function(r){$("#center").css("overflow","auto");view=this;var t=this;var s=new e({id:r.id});s.url=s.attributes.urlRoot+r.id+"/contents";s.fetch({success:function(u){for(var w=0;w<s.attributes.folder.models.length;w++){var v=s.attributes.folder.models[w];if(v.get("type")==="file"){v.set("readable_size",t.size_to_string(v.get("file_size")))}}var y=s.full_path;var z;if(y.length===1){z=0}else{z=y[y.length-2][0]}var x=_.template(t.templateFolder(),{path:s.full_path,items:s.attributes.folder.models,id:r.id,upper_folder_id:z});t.$el.html(x)},error:function(){n.error("An error occured :(")}})},size_to_string:function(r){var s="";if(r>=100000000000){r=r/100000000000;s="TB"}else{if(r>=100000000){r=r/100000000;s="GB"}else{if(r>=100000){r=r/100000;s="MB"}else{if(r>=100){r=r/100;s="KB"}else{r=r*10;s="b"}}}}return(Math.round(r)/10)+s},navigateToFolder:function(s){var r=$(s.target).attr("data-id");if(typeof r==="undefined"){return false}else{if(r==="0"){library_router.navigate("#",{trigger:true,replace:true})}else{library_router.navigate("folders/"+r,{trigger:true,replace:true})}}},showDatasetDetails:function(u){u.preventDefault();var v=$(u.target).parent().parent().attr("id");var t=new i();var s=new p();t.id=v;var r=this;t.fetch({success:function(w){s.fetch({success:function(x){r.renderModalAfterFetch(w,x)},error:function(){n.error("An error occured during fetching histories:(");r.renderModalAfterFetch(w)}})},error:function(){n.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(w,t){var u=this.size_to_string(w.get("file_size"));var v=_.template(this.templateDatasetModal(),{item:w,size:u});var s=this;this.modal=new k.GalaxyModal({destructible:true,title:"Dataset Details",body:v,buttons:{Import:function(){s.importCurrentIntoHistory()},Download:function(){s.downloadCurrent()},Close:function(){s.modal.hideOrDestroy()}}});$(".peek").html(w.get("peek"));if(typeof history.models!==undefined){var r=_.template(this.templateHistorySelectInModal(),{histories:t.models});$(this.modal.elMain).find(".buttons").prepend(r);if(s.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(s.lastSelectedHistory)}}this.modal.bindEvents();this.modal.show()},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var r=[];r.push($("#id_row").attr("data-id"));var s="/api/libraries/datasets/download/uncompressed";var t={ldda_ids:r};folderContentView.processDownload(s,t);this.modal.enableButton("Import");this.modal.enableButton("Download")},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var t=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=t;var r=$("#id_row").attr("data-id");var u=new b();var s=this;u.url=u.urlRoot+t+"/contents";u.save({content:r,source:"library"},{success:function(){n.success("Dataset imported");s.modal.enableButton("Import");s.modal.enableButton("Download")},error:function(){n.error("An error occured! Dataset not imported. Please try again.");s.modal.enableButton("Import");s.modal.enableButton("Download")}})},selectAll:function(s){var r=s.target.checked;that=this;$(":checkbox").each(function(){this.checked=r;$row=$(this.parentElement.parentElement);(r)?that.makeDarkRow($row):that.makeWhiteRow($row)});this.checkTools()},selectClickedRow:function(s){var u="";var r;var t;if(s.target.localName==="input"){u=s.target;r=$(s.target.parentElement.parentElement);t="input"}else{if(s.target.localName==="td"){u=$("#"+s.target.parentElement.id).find(":checkbox")[0];r=$(s.target.parentElement);t="td"}}if(u===""){s.stopPropagation();return}if(u===undefined){s.stopPropagation();return}if(u.checked){if(t==="td"){u.checked="";this.makeWhiteRow(r)}else{if(t==="input"){this.makeDarkRow(r)}}}else{if(t==="td"){u.checked="selected";this.makeDarkRow(r)}else{if(t==="input"){this.makeWhiteRow(r)}}}this.checkTools()},makeDarkRow:function(r){r.removeClass("light");r.find("a").removeClass("light");r.addClass("dark");r.find("a").addClass("dark")},makeWhiteRow:function(r){r.removeClass("dark");r.find("a").removeClass("dark");r.addClass("light");r.find("a").addClass("light")},checkTools:function(){var r=$("#folder_table").find(":checked");if(r.length>0){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}else{$("#toolbtn_bulk_import").hide();$("#toolbtn_dl").hide()}},modalBulkImport:function(){var s=this;var r=new p();r.fetch({success:function(t){var u=_.template(s.templateBulkImportInModal(),{histories:t.models});s.modal=new k.GalaxyModal({destructible:true,title:"Import into History",body:u,buttons:{Import:function(){s.importAllIntoHistory()},Close:function(){s.modal.hideOrDestroy()}}});s.modal.bindEvents();s.modal.show()},error:function(){n.error("An error occured :(")}})},importAllIntoHistory:function(){this.modal.disableButton("Import");var t=$("select[name=dataset_import_bulk] option:selected").val();var x=$("select[name=dataset_import_bulk] option:selected").text();var z=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){z.push(this.parentElement.parentElement.id)}});var y=_.template(this.templateProgressBar(),{history_name:x});$(this.modal.elMain).find(".modal-body").html(y);var u=100/z.length;this.initProgress(u);var r=[];for(var s=z.length-1;s>=0;s--){library_dataset_id=z[s];var v=new b();var w=this;v.url=v.urlRoot+t+"/contents";v.content=library_dataset_id;v.source="library";r.push(v)}this.chainCall(r)},chainCall:function(s){var r=this;var t=s.pop();if(typeof t==="undefined"){n.success("All datasets imported");this.modal.hideOrDestroy();return}var u=$.when(t.save({content:t.content,source:t.source})).done(function(v){r.updateProgress();responses.push(v);r.chainCall(s)})},initProgress:function(r){this.progress=0;this.progressStep=r},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(r,v){var t=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){t.push(this.parentElement.parentElement.id)}});var s="/api/libraries/datasets/download/"+v;var u={ldda_ids:t};this.processDownload(s,u,"get")},processDownload:function(s,t,u){if(s&&t){t=typeof t=="string"?t:$.param(t);var r="";$.each(t.split("&"),function(){var v=this.split("=");r+='<input type="hidden" name="'+v[0]+'" value="'+v[1]+'" />'});$('<form action="'+s+'" method="'+(u||"post")+'">'+r+"</form>").appendTo("body").submit().remove();n.info("Your download will begin soon")}},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,title:"Create New Folder",body:this.templateNewFolderInModal(),buttons:{Create:function(){r.create_new_folder_event()},Close:function(){r.modal.hideOrDestroy();r.modal=null}}});this.modal.bindEvents();this.modal.show()},create_new_folder_event:function(){var r=this.serialize_new_folder();if(this.validate_new_folder(r)){var t=new c();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];t.url=t.urlRoot+"/"+current_folder_id;var s=this;t.save(r,{success:function(u){s.modal.hideOrDestroy();n.success("Folder created");s.render({id:current_folder_id})},error:function(){n.error("An error occured :(")}})}else{n.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(r){return r.name!==""}});var a=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"show_library_modal"},initialize:function(){},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; overflow: auto !important; ">');tmpl_array.push("");tmpl_array.push('<h3>New Data Libraries. This is work in progress. Report problems & ideas to <a href="mailto:marten@bx.psu.edu?Subject=DataLibraries_Feedback" target="_blank">Marten</a>.</h3>');tmpl_array.push('<a href="" id="create_new_library_btn" class="btn btn-primary file ">New Library</a>');tmpl_array.push('<table class="table table-condensed">');tmpl_array.push(" <thead>");tmpl_array.push(' <th class="button_heading"></th>');tmpl_array.push(" <th>name</th>");tmpl_array.push(" <th>description</th>");tmpl_array.push(" <th>synopsis</th> ");tmpl_array.push(" <th>model type</th> ");tmpl_array.push(" </thead>");tmpl_array.push(" <tbody>");tmpl_array.push(" <% _.each(libraries, function(library) { %>");tmpl_array.push(" <tr>");tmpl_array.push(' <td><button title="Open this library" type="button" data-id="<%- library.get("root_folder_id") %>" class="btn_open_folder btn btn-default btn-xs">');tmpl_array.push(' <span class="fa fa-folder-open"></span> browse</td>');tmpl_array.push(' <td><%- library.get("name") %></td>');tmpl_array.push(' <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("model_class")) %></td>');tmpl_array.push(" </tr>");tmpl_array.push(" <% }); %>");tmpl_array.push(" </tbody>");tmpl_array.push("</table>");tmpl_array.push("</div>");return tmpl_array.join("")},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")},render:function(){$("#center").css("overflow","auto");var r=this;libraries=new o();libraries.fetch({success:function(s){var t=_.template(r.templateLibraryList(),{libraries:s.models});r.$el.html(t)},error:function(t,s){if(s.statusCode().status===403){n.error("Please log in first. Redirecting to login page in 3s.");setTimeout(r.redirectToLogin,3000)}else{n.error("An error occured. Please try again.")}}})},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},modal:null,show_library_modal:function(s){s.preventDefault();s.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){r.create_new_library_event()},Close:function(){r.modal.hideOrDestroy()}}});this.modal.bindEvents();this.modal.show()},create_new_library_event:function(){var t=this.serialize_new_library();if(this.validate_new_library(t)){var s=new f();var r=this;s.save(t,{success:function(u){r.modal.hideOrDestroy();r.clear_library_modal();r.render();n.success("Library created")},error:function(){n.error("An error occured :(")}})}else{n.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(r){return r.name!==""}});var g=Backbone.View.extend({folderContentView:null,galaxyLibraryview:null,initialize:function(){folderContentView=new m();galaxyLibraryview=new a();library_router=new q();library_router.on("route:libraries",function(){galaxyLibraryview.render()});library_router.on("route:folder_content",function(r){folderContentView.render({id:r})});library_router.on("route:download",function(r,s){if($("#center").find(":checked").length===0){library_router.navigate("folders/"+r,{trigger:true,replace:true})}else{folderContentView.download(r,s);library_router.navigate("folders/"+r,{trigger:false,replace:true})}});Backbone.history.start();return this}});return{GalaxyApp:g}});
\ No newline at end of file
+var view=null;var library_router=null;var responses=[];define(["galaxy.modal","galaxy.masthead","utils/galaxy.utils","libs/toastr"],function(k,l,h,n){var f=Backbone.Model.extend({urlRoot:"/api/libraries"});var c=Backbone.Model.extend({urlRoot:"/api/folders"});var o=Backbone.Collection.extend({url:"/api/libraries",model:f});var i=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var d=Backbone.Collection.extend({model:i});var e=Backbone.Model.extend({defaults:{folder:new d(),full_path:"unknown",urlRoot:"/api/folders/",id:"unknown"},parse:function(r){this.full_path=r[0].full_path;this.get("folder").reset(r[1].folder_contents);return r}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var j=Backbone.Model.extend({url:"/api/histories/"});var p=Backbone.Collection.extend({url:"/api/histories",model:j});var q=Backbone.Router.extend({routes:{"":"libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var m=Backbone.View.extend({el:"#center",progress:0,progressStep:1,lastSelectedHistory:"",modal:null,folders:null,initialize:function(){this.folders=[];this.queue=jQuery.Deferred();this.queue.resolve()},templateFolder:function(){var r=[];r.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');r.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');r.push('<div id="library_folder_toolbar" >');r.push(' <button title="Create New Folder" id="toolbtn_create_folder" class="btn btn-primary" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');r.push(' <button id="toolbtn_bulk_import" class="btn btn-primary" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-external-link"></span> to history</button>');r.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');r.push(' <button id="drop_toggle" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">');r.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');r.push(" </button>");r.push(' <ul class="dropdown-menu" role="menu">');r.push(' <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');r.push(" </ul>");r.push(" </div>");r.push("</div>");r.push('<div class="library_breadcrumb">');r.push('<a title="Return to the list of libraries" href="#">Libraries</a><b>|</b> ');r.push("<% _.each(path, function(path_item) { %>");r.push("<% if (path_item[0] != id) { %>");r.push('<a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a><b>|</b> ');r.push("<% } else { %>");r.push('<span title="You are in this folder"><%- path_item[1] %></span>');r.push("<% } %>");r.push("<% }); %>");r.push("</div>");r.push('<table id="folder_table" class="table table-condensed">');r.push(" <thead>");r.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');r.push(' <th class="button_heading">view</th>');r.push(" <th>name</th>");r.push(" <th>data type</th>");r.push(" <th>size</th>");r.push(" <th>date (UTC)</th>");r.push(" </thead>");r.push(" <tbody>");r.push(" <td></td>");r.push(' <td><button title="Go to parent folder" type="button" data-id="<%- upper_folder_id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-arrow-up"></span> .. go up</td>');r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" </tr>");r.push(" <% _.each(items, function(content_item) { %>");r.push(' <tr class="folder_row light" id="<%- content_item.id %>">');r.push(' <% if (content_item.get("type") === "folder") { %>');r.push(" <td></td>");r.push(' <td><button title="Open this folder" type="button" data-id="<%- content_item.id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-folder-open"></span> browse</td>');r.push(' <td><%- content_item.get("name") %>');r.push(' <% if (content_item.get("item_count") === 0) { %>');r.push(' <span class="muted">(empty folder)</span>');r.push(" <% } %>");r.push(" </td>");r.push(" <td>folder</td>");r.push(' <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>');r.push(" <% } else { %>");r.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');r.push(" <td>");r.push(' <button title="See details of this dataset" type="button" class="library-dataset btn btn-default btn-xs">');r.push(' <span class="fa fa-eye"></span> details');r.push(" </button>");r.push(" </td>");r.push(' <td><%- content_item.get("name") %></td>');r.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');r.push(' <td><%= _.escape(content_item.get("readable_size")) %></td>');r.push(" <% } %> ");r.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>');r.push(" </tr>");r.push(" <% }); %>");r.push(" ");r.push(" </tbody>");r.push("</table>");r.push("</div>");return r.join("")},templateDatasetModal:function(){var r=[];r.push('<div id="dataset_info_modal">');r.push(' <table class="table table-striped table-condensed">');r.push(" <tr>");r.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');r.push(' <td><%= _.escape(item.get("name")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Data type</th>');r.push(' <td><%= _.escape(item.get("data_type")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Genome build</th>');r.push(' <td><%= _.escape(item.get("genome_build")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Size</th>');r.push(" <td><%= _.escape(size) %></td>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Date uploaded (UTC)</th>');r.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Uploaded by</th>');r.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');r.push(" </tr>");r.push(' <tr scope="row">');r.push(' <th scope="row">Data Lines</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Comment Lines</th>');r.push(' <% if (item.get("metadata_comment_lines") === "") { %>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');r.push(" <% } else { %>");r.push(' <td scope="row">unknown</td>');r.push(" <% } %>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Number of Columns</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Column Types</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Miscellaneous information</th>');r.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');r.push(" </tr>");r.push(" </table>");r.push(' <pre class="peek">');r.push(" </pre>");r.push("</div>");return r.join("")},templateHistorySelectInModal:function(){var r=[];r.push('<span id="history_modal_combo" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateBulkImportInModal:function(){var r=[];r.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateProgressBar:function(){var r=[];r.push('<div class="import_text">');r.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");r.push("</div>");r.push('<div class="progress">');r.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');r.push(' <span class="completion_span">0% Complete</span>');r.push(" </div>");r.push("</div>");r.push("");return r.join("")},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return tmpl_array.join("")},events:{"click #select-all-checkboxes":"selectAll","click .folder_row":"selectClickedRow","click #toolbtn_bulk_import":"modalBulkImport","click #toolbtn_dl":"bulkDownload","click .library-dataset":"showDatasetDetails","click #toolbtn_create_folder":"createFolderFromModal","click .btn_open_folder":"navigateToFolder"},render:function(r){$("#center").css("overflow","auto");view=this;var t=this;var s=new e({id:r.id});s.url=s.attributes.urlRoot+r.id+"/contents";s.fetch({success:function(u){for(var w=0;w<s.attributes.folder.models.length;w++){var v=s.attributes.folder.models[w];if(v.get("type")==="file"){v.set("readable_size",t.size_to_string(v.get("file_size")))}}var y=s.full_path;var z;if(y.length===1){z=0}else{z=y[y.length-2][0]}var x=_.template(t.templateFolder(),{path:s.full_path,items:s.attributes.folder.models,id:r.id,upper_folder_id:z});t.$el.html(x)},error:function(){n.error("An error occured :(")}})},size_to_string:function(r){var s="";if(r>=100000000000){r=r/100000000000;s="TB"}else{if(r>=100000000){r=r/100000000;s="GB"}else{if(r>=100000){r=r/100000;s="MB"}else{if(r>=100){r=r/100;s="KB"}else{r=r*10;s="b"}}}}return(Math.round(r)/10)+s},navigateToFolder:function(s){var r=$(s.target).attr("data-id");if(typeof r==="undefined"){return false}else{if(r==="0"){library_router.navigate("#",{trigger:true,replace:true})}else{library_router.navigate("folders/"+r,{trigger:true,replace:true})}}},showDatasetDetails:function(u){u.preventDefault();var v=$(u.target).parent().parent().attr("id");var t=new i();var s=new p();t.id=v;var r=this;t.fetch({success:function(w){s.fetch({success:function(x){r.renderModalAfterFetch(w,x)},error:function(){n.error("An error occured during fetching histories:(");r.renderModalAfterFetch(w)}})},error:function(){n.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(w,t){var u=this.size_to_string(w.get("file_size"));var v=_.template(this.templateDatasetModal(),{item:w,size:u});var s=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Dataset Details",body:v,buttons:{Import:function(){s.importCurrentIntoHistory()},Download:function(){s.downloadCurrent()},Close:function(){s.modal.hideOrDestroy()}}});$(".peek").html(w.get("peek"));if(typeof history.models!==undefined){var r=_.template(this.templateHistorySelectInModal(),{histories:t.models});$(this.modal.elMain).find(".buttons").prepend(r);if(s.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(s.lastSelectedHistory)}}this.modal.show()},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var r=[];r.push($("#id_row").attr("data-id"));var s="/api/libraries/datasets/download/uncompressed";var t={ldda_ids:r};folderContentView.processDownload(s,t);this.modal.enableButton("Import");this.modal.enableButton("Download")},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var t=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=t;var r=$("#id_row").attr("data-id");var u=new b();var s=this;u.url=u.urlRoot+t+"/contents";u.save({content:r,source:"library"},{success:function(){n.success("Dataset imported");s.modal.enableButton("Import");s.modal.enableButton("Download")},error:function(){n.error("An error occured! Dataset not imported. Please try again.");s.modal.enableButton("Import");s.modal.enableButton("Download")}})},selectAll:function(s){var r=s.target.checked;that=this;$(":checkbox").each(function(){this.checked=r;$row=$(this.parentElement.parentElement);(r)?that.makeDarkRow($row):that.makeWhiteRow($row)});this.checkTools()},selectClickedRow:function(s){var u="";var r;var t;if(s.target.localName==="input"){u=s.target;r=$(s.target.parentElement.parentElement);t="input"}else{if(s.target.localName==="td"){u=$("#"+s.target.parentElement.id).find(":checkbox")[0];r=$(s.target.parentElement);t="td"}}if(u===""){s.stopPropagation();return}if(u===undefined){s.stopPropagation();return}if(u.checked){if(t==="td"){u.checked="";this.makeWhiteRow(r)}else{if(t==="input"){this.makeDarkRow(r)}}}else{if(t==="td"){u.checked="selected";this.makeDarkRow(r)}else{if(t==="input"){this.makeWhiteRow(r)}}}this.checkTools()},makeDarkRow:function(r){r.removeClass("light");r.find("a").removeClass("light");r.addClass("dark");r.find("a").addClass("dark")},makeWhiteRow:function(r){r.removeClass("dark");r.find("a").removeClass("dark");r.addClass("light");r.find("a").addClass("light")},checkTools:function(){var r=$("#folder_table").find(":checked");if(r.length>0){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}else{$("#toolbtn_bulk_import").hide();$("#toolbtn_dl").hide()}},modalBulkImport:function(){var s=this;var r=new p();r.fetch({success:function(t){var u=_.template(s.templateBulkImportInModal(),{histories:t.models});s.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Import into History",body:u,buttons:{Import:function(){s.importAllIntoHistory()},Close:function(){s.modal.hideOrDestroy()}}});s.modal.show()},error:function(){n.error("An error occured :(")}})},importAllIntoHistory:function(){this.modal.disableButton("Import");var t=$("select[name=dataset_import_bulk] option:selected").val();var x=$("select[name=dataset_import_bulk] option:selected").text();var z=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){z.push(this.parentElement.parentElement.id)}});var y=_.template(this.templateProgressBar(),{history_name:x});$(this.modal.elMain).find(".modal-body").html(y);var u=100/z.length;this.initProgress(u);var r=[];for(var s=z.length-1;s>=0;s--){library_dataset_id=z[s];var v=new b();var w=this;v.url=v.urlRoot+t+"/contents";v.content=library_dataset_id;v.source="library";r.push(v)}this.chainCall(r)},chainCall:function(s){var r=this;var t=s.pop();if(typeof t==="undefined"){n.success("All datasets imported");this.modal.hideOrDestroy();return}var u=$.when(t.save({content:t.content,source:t.source})).done(function(v){r.updateProgress();responses.push(v);r.chainCall(s)})},initProgress:function(r){this.progress=0;this.progressStep=r},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(r,v){var t=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){t.push(this.parentElement.parentElement.id)}});var s="/api/libraries/datasets/download/"+v;var u={ldda_ids:t};this.processDownload(s,u,"get")},processDownload:function(s,t,u){if(s&&t){t=typeof t=="string"?t:$.param(t);var r="";$.each(t.split("&"),function(){var v=this.split("=");r+='<input type="hidden" name="'+v[0]+'" value="'+v[1]+'" />'});$('<form action="'+s+'" method="'+(u||"post")+'">'+r+"</form>").appendTo("body").submit().remove();n.info("Your download will begin soon")}},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Create New Folder",body:this.templateNewFolderInModal(),buttons:{Create:function(){r.create_new_folder_event()},Close:function(){r.modal.hideOrDestroy();r.modal=null}}});this.modal.show()},create_new_folder_event:function(){var r=this.serialize_new_folder();if(this.validate_new_folder(r)){var t=new c();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];t.url=t.urlRoot+"/"+current_folder_id;var s=this;t.save(r,{success:function(u){s.modal.hideOrDestroy();n.success("Folder created");s.render({id:current_folder_id})},error:function(){n.error("An error occured :(")}})}else{n.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(r){return r.name!==""}});var a=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"show_library_modal"},initialize:function(){},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; overflow: auto !important; ">');tmpl_array.push("");tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push('<a href="" id="create_new_library_btn" class="btn btn-primary file ">New Library</a>');tmpl_array.push('<table class="table table-condensed">');tmpl_array.push(" <thead>");tmpl_array.push(' <th class="button_heading"></th>');tmpl_array.push(" <th>name</th>");tmpl_array.push(" <th>description</th>");tmpl_array.push(" <th>synopsis</th> ");tmpl_array.push(" <th>model type</th> ");tmpl_array.push(" </thead>");tmpl_array.push(" <tbody>");tmpl_array.push(" <% _.each(libraries, function(library) { %>");tmpl_array.push(" <tr>");tmpl_array.push(' <td><button title="Open this library" type="button" data-id="<%- library.get("root_folder_id") %>" class="btn_open_folder btn btn-default btn-xs">');tmpl_array.push(' <span class="fa fa-folder-open"></span> browse</td>');tmpl_array.push(' <td><%- library.get("name") %></td>');tmpl_array.push(' <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("model_class")) %></td>');tmpl_array.push(" </tr>");tmpl_array.push(" <% }); %>");tmpl_array.push(" </tbody>");tmpl_array.push("</table>");tmpl_array.push("</div>");return tmpl_array.join("")},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")},render:function(){$("#center").css("overflow","auto");var r=this;libraries=new o();libraries.fetch({success:function(s){var t=_.template(r.templateLibraryList(),{libraries:s.models});r.$el.html(t)},error:function(t,s){if(s.statusCode().status===403){n.info("Please log in first. Redirecting to login page in 3s.");setTimeout(r.redirectToLogin,3000)}else{n.error("An error occured. Please try again.")}}})},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},modal:null,show_library_modal:function(s){s.preventDefault();s.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){r.create_new_library_event()},Close:function(){r.modal.hideOrDestroy()}}});this.modal.show()},create_new_library_event:function(){var t=this.serialize_new_library();if(this.validate_new_library(t)){var s=new f();var r=this;s.save(t,{success:function(u){r.modal.hideOrDestroy();r.clear_library_modal();r.render();n.success("Library created")},error:function(){n.error("An error occured :(")}})}else{n.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(r){return r.name!==""}});var g=Backbone.View.extend({folderContentView:null,galaxyLibraryview:null,initialize:function(){folderContentView=new m();galaxyLibraryview=new a();library_router=new q();library_router.on("route:libraries",function(){galaxyLibraryview.render()});library_router.on("route:folder_content",function(r){folderContentView.render({id:r})});library_router.on("route:download",function(r,s){if($("#center").find(":checked").length===0){library_router.navigate("folders/"+r,{trigger:true,replace:true})}else{folderContentView.download(r,s);library_router.navigate("folders/"+r,{trigger:false,replace:true})}});Backbone.history.start();return this}});return{GalaxyApp:g}});
\ No newline at end of file
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 static/scripts/packed/galaxy.modal.js
--- a/static/scripts/packed/galaxy.modal.js
+++ b/static/scripts/packed/galaxy.modal.js
@@ -1,1 +1,1 @@
-define([],function(){var a=Backbone.View.extend({elMain:"#everything",optionsDefault:{title:"galaxy-modal",body:"",backdrop:true,height:null,width:null},options:{destructible:false},initialize:function(b){self=this;if(b){this.create(b)}},hideOrDestroy:function(){if(this.options.destructible){self.destroy()}else{self.hide()}},bindEvents:function(){$(document).on("keyup",function(b){if(b.keyCode==27){self.hideOrDestroy()}});$("html").on("click",function(b){self.hideOrDestroy()});$(".modal-content").on("click",function(b){b.stopPropagation()})},unbindEvents:function(){$(document).off("keyup",function(b){if(b.keyCode==27){self.hideOrDestroy()}});$("html").off("click",function(b){self.hideOrDestroy()});$(".modal-content").off("click",function(b){b.stopPropagation()})},show:function(b){this.initialize(b);if(this.options.height){this.$body.css("height",this.options.height);this.$body.css("overflow","hidden")}else{this.$body.css("max-height",$(window).height()/2)}if(this.options.width){this.$dialog.css("width",this.options.width)}if(this.visible){this.$el.show()}else{this.$el.fadeIn("fast")}this.visible=true},hide:function(){this.$el.fadeOut("fast");this.visible=false;this.unbindEvents()},destroy:function(){this.visible=false;this.unbindEvents();this.$el.remove()},create:function(c){this.options=_.defaults(c,this.optionsDefault);if(this.options.body=="progress"){this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')}if(this.$el){this.$el.remove()}this.setElement(this.template(this.options.title));this.$dialog=(this.$el).find(".modal-dialog");this.$body=(this.$el).find(".modal-body");this.$footer=(this.$el).find(".modal-footer");this.$buttons=(this.$el).find(".buttons");this.$backdrop=(this.$el).find(".modal-backdrop");this.$body.html(this.options.body);if(!this.options.backdrop){this.$backdrop.removeClass("in")}if(this.options.buttons){var b=this;$.each(this.options.buttons,function(d,e){b.$buttons.append($('<button id="'+String(d).toLowerCase()+'"></button>').text(d).click(e)).append(" ")})}else{this.$footer.hide()}$(this.elMain).append($(this.el))},enableButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).prop("disabled",false)},disableButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).prop("disabled",true)},hideButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).hide()},showButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).show()},scrollTop:function(){return this.$body.scrollTop()},template:function(b){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+b+'</h4></div><div class="modal-body"></div><div class="modal-footer"><div class="buttons" style="float: right;"></div></div></div</div></div>'}});return{GalaxyModal:a}});
\ No newline at end of file
+define([],function(){var a=Backbone.View.extend({elMain:"#everything",optionsDefault:{title:"galaxy-modal",body:"",backdrop:true,height:null,width:null},eventsBound:false,options:{destructible:false,bindClosingEvents:false},initialize:function(b){self=this;if(b){this.create(b)}},hideOrDestroy:function(){self.visible=false;self.unbindEvents();if(self.options.destructible){self.$el.remove()}else{self.hide()}},hide:function(){this.visible=false;this.$el.fadeOut("fast")},bindEvents:function(){$(document).on("keyup",function(b){if(b.keyCode==27){self.hideOrDestroy()}});$("html").on("click",self.hideOrDestroy);$(".modal-content").on("click",function(b){b.stopPropagation()});self.eventsBound=true},unbindEvents:function(){$(document).off("keyup",function(b){if(b.keyCode==27){self.hideOrDestroy()}});$("html").off("click",function(b){self.hideOrDestroy()});$(".modal-content").off("click",function(b){b.stopPropagation()});self.eventsBound=false},show:function(b){this.initialize(b);if(this.options.height){this.$body.css("height",this.options.height);this.$body.css("overflow","hidden")}else{this.$body.css("max-height",$(window).height()/2)}if(this.options.width){this.$dialog.css("width",this.options.width)}if(this.visible){this.$el.show()}else{this.$el.fadeIn("fast")}this.visible=true},create:function(c){this.options=_.defaults(c,this.optionsDefault);if(this.options.body=="progress"){this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')}if(this.$el){this.$el.remove()}this.setElement(this.template(this.options.title));this.$dialog=(this.$el).find(".modal-dialog");this.$body=(this.$el).find(".modal-body");this.$footer=(this.$el).find(".modal-footer");this.$buttons=(this.$el).find(".buttons");this.$backdrop=(this.$el).find(".modal-backdrop");this.$body.html(this.options.body);if(!this.options.backdrop){this.$backdrop.removeClass("in")}if(this.options.buttons){var b=this;$.each(this.options.buttons,function(d,e){b.$buttons.append($('<button id="'+String(d).toLowerCase()+'"></button>').text(d).click(e)).append(" ")})}else{this.$footer.hide()}$(this.elMain).append($(this.el));if(this.options.bindClosingEvents&&!this.eventsBound){this.bindEvents()}},enableButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).prop("disabled",false)},disableButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).prop("disabled",true)},hideButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).hide()},showButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).show()},scrollTop:function(){return this.$body.scrollTop()},template:function(b){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+b+'</h4></div><div class="modal-body"></div><div class="modal-footer"><div class="buttons" style="float: right;"></div></div></div</div></div>'}});return{GalaxyModal:a}});
\ No newline at end of file
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 templates/webapps/tool_shed/common/common.mako
--- a/templates/webapps/tool_shed/common/common.mako
+++ b/templates/webapps/tool_shed/common/common.mako
@@ -51,6 +51,23 @@
</script></%def>
+<%def name="render_deprecated_repository_dependencies_message( deprecated_repository_dependency_tups )">
+ <div class="warningmessage">
+ <%
+ from tool_shed.util.common_util import parse_repository_dependency_tuple
+ msg = '<ul>'
+ for deprecated_repository_dependency_tup in deprecated_repository_dependency_tups:
+ toolshed, name, owner, changeset_revision, pir, oicct = \
+ parse_repository_dependency_tuple( deprecated_repository_dependency_tup )
+ msg += '<li>Revision <b>%s</b> of repository <b>%s</b> owned by <b>%s</b></li>' % \
+ ( changeset_revision, name, owner )
+ msg += '</ul>'
+ %>
+ This repository depends upon the following deprecated repositories<br/>
+ ${msg}
+ </div>
+</%def>
+
<%def name="render_star_rating( name, rating, disabled=False )"><%
if disabled:
@@ -87,6 +104,20 @@
</div></%def>
+<%def name="render_multiple_heads_message( heads )">
+ <div class="warningmessage">
+ <%
+ from tool_shed.util.shed_util_common import get_revision_label_from_ctx
+ heads_str = ''
+ for ctx in heads:
+ heads_str += '%s<br/>' % get_revision_label_from_ctx( ctx, include_date=True )
+ %>
+ Contact the administrator of this Tool Shed as soon as possible and let them know that
+ this repository has the following multiple heads which must be merged.<br/>
+ ${heads_str}
+ </div>
+</%def>
+
<%def name="render_review_comment( comment_text )"><style type="text/css">
#reviews_table{ table-layout:fixed;
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 templates/webapps/tool_shed/repository/manage_repository.mako
--- a/templates/webapps/tool_shed/repository/manage_repository.mako
+++ b/templates/webapps/tool_shed/repository/manage_repository.mako
@@ -87,6 +87,14 @@
multiple_heads = len( heads ) > 1
else:
multiple_heads = False
+
+ if repository_metadata is None:
+ revision_installable = False
+ else:
+ if repository_metadata.downloadable is None:
+ revision_installable = 'unknown'
+ else:
+ revision_installable = repository_metadata.downloadable
%><%!
@@ -119,18 +127,12 @@
<div class="warningmessage">
This repository has been marked as deprecated, so some tool shed features may be restricted.
</div>
-%elif multiple_heads:
- <div class="warningmessage">
- <%
- from tool_shed.util.shed_util_common import get_revision_label_from_ctx
- heads_str = ''
- for ctx in heads:
- heads_str += '%s<br/>' % get_revision_label_from_ctx( ctx, include_date=True )
- %>
- Contact the administrator of this Tool Shed as soon as possible and let them know that
- this repository has the following multiple heads which must be merged.<br/>
- ${heads_str}
- </div>
+%endif:
+%if multiple_heads:
+ ${render_multiple_heads_message( heads )}
+%endif
+%if deprecated_repository_dependency_tups:
+ ${render_deprecated_repository_dependencies_message( deprecated_repository_dependency_tups )}
%endif
%if len( changeset_revision_select_field.options ) > 1:
@@ -207,7 +209,11 @@
${repository.user.username | h}
</div><div class="form-row">
- <label>Times downloaded:</label>
+ <label>This revision can be installed:</label>
+ ${revision_installable}
+ </div>
+ <div class="form-row">
+ <label>Times cloned / installed:</label>
${repository.times_downloaded | h}
</div>
%if is_admin:
diff -r a4108edecdd5bfc9cc185866429bfa8297cab41e -r ed3e84645aa2488b5fc046ed50e3fdfd9fd52588 templates/webapps/tool_shed/repository/view_repository.mako
--- a/templates/webapps/tool_shed/repository/view_repository.mako
+++ b/templates/webapps/tool_shed/repository/view_repository.mako
@@ -30,6 +30,14 @@
multiple_heads = len( heads ) > 1
else:
multiple_heads = False
+
+ if repository_metadata is None:
+ revision_installable = False
+ else:
+ if repository_metadata.downloadable is None:
+ revision_installable = 'unknown'
+ else:
+ revision_installable = repository_metadata.downloadable
%><%!
@@ -66,18 +74,12 @@
<div class="warningmessage">
This repository has been marked as deprecated, so some tool shed features may be restricted.
</div>
-%elif multiple_heads:
- <div class="warningmessage">
- <%
- from tool_shed.util.shed_util_common import get_revision_label_from_ctx
- heads_str = ''
- for ctx in heads:
- heads_str += '%s<br/>' % get_revision_label_from_ctx( ctx, include_date=True )
- %>
- Contact the administrator of this Tool Shed as soon as possible and let them know that
- this repository has the following multiple heads which must be merged.<br/>
- ${heads_str}
- </div>
+%endif:
+%if multiple_heads:
+ ${render_multiple_heads_message( heads )}
+%endif
+%if deprecated_repository_dependency_tups:
+ ${render_deprecated_repository_dependencies_message( deprecated_repository_dependency_tups )}
%endif
%if len( changeset_revision_select_field.options ) > 1:
@@ -142,7 +144,11 @@
${repository.user.username | h}
</div><div class="form-row">
- <label>Times downloaded:</label>
+ <label>This revision can be installed:</label>
+ ${revision_installable}
+ </div>
+ <div class="form-row">
+ <label>Times cloned / installed:</label>
${repository.times_downloaded}
</div>
%if trans.user_is_admin():
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
4 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/4e2f60de42fa/
Changeset: 4e2f60de42fa
Branch: search
User: kellrott
Date: 2014-01-14 17:14:42
Summary: Default merge
Affected #: 376 files
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/config/charts.xml
--- /dev/null
+++ b/config/plugins/visualizations/charts/config/charts.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE visualization SYSTEM "../../visualization.dtd">
+<visualization name="charts">
+ <data_sources>
+ <data_source>
+ <model_class>HistoryDatasetAssociation</model_class>
+ <test type="isinstance" test_attr="datatype" result_type="datatype">tabular.Tabular</test>
+ <to_param param_attr="id">dataset_id</to_param>
+ </data_source>
+ </data_sources>
+ <params>
+ <param type="dataset" var_name_in_template="hda" required="true">dataset_id</param>
+ </params>
+ <template>charts.mako</template>
+</visualization>
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/sample.txt
--- /dev/null
+++ b/config/plugins/visualizations/charts/sample.txt
@@ -0,0 +1,9 @@
+43 55 63 99 28 85 20 31 47 14
+1 63 94 83 94 74 7 73 51 7
+8 34 2 94 87 21 72 51 3 84
+5 50 40 30 59 43 19 77 30 80
+22 55 69 43 77 72 12 54 53 56
+36 34 81 28 59 64 54 29 57 69
+57 90 93 32 45 98 40 16 52 83
+6 17 39 86 10 11 38 69 19 50
+67 51 47 22 58 27 65 49 92 96
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/app.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/app.js
@@ -0,0 +1,67 @@
+// dependencies
+define(['library/portlet', 'library/ui', 'library/utils',
+ 'main', 'viewport', 'create', 'config',
+ 'models/datasets', 'models/chart', 'models/charts', 'models/types'],
+ function( Portlet, Ui, Utils,
+ Main, Viewport, Create, Config,
+ Datasets, Chart, Charts, Types
+ ) {
+
+// widget
+return Backbone.View.extend(
+{
+ // initialize
+ initialize: function(options)
+ {
+ // link options
+ this.options = options;
+
+ // link galaxy
+ this.modal = parent.Galaxy.modal;
+
+ // create chart objects
+ this.types = new Types();
+ this.chart = new Chart();
+ this.charts = new Charts(this);
+
+ // create dataset handler
+ this.datasets = new Datasets(this);
+
+ // create views
+ this.main = new Main(this);
+ this.viewport = new Viewport(this);
+ this.config = new Config(this);
+ this.create = new Create(this);
+
+ // portlet
+ this.portlet = new Portlet({icon : 'fa-bar-chart-o', label : 'Charts'});
+ this.portlet.append(this.main.$el);
+ this.portlet.append(this.config.$el);
+ this.portlet.append(this.create.$el);
+
+ // append main
+ this.main.append(this.viewport.$el);
+
+ // create
+ this.config.$el.hide();
+ this.create.$el.hide();
+
+ // set elements
+ this.setElement(this.portlet.$el);
+ },
+
+ // execute command
+ execute: function(options) {
+ },
+
+ // unload
+ onunload: function() {
+ },
+
+ // log
+ log: function(location, message) {
+ console.log(location + ' ' + message);
+ }
+});
+
+});
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/charts/bardiagram.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/charts/bardiagram.js
@@ -0,0 +1,34 @@
+// dependencies
+define(['library/utils'], function(Utils) {
+
+// widget
+return Backbone.View.extend(
+{
+ // initialize
+ initialize: function(app, options) {
+ this.app = app;
+ this.options = options;
+ this.chart = options.chart;
+ },
+
+ // render
+ refresh : function(data)
+ {
+ // add graph to screen
+ var self = this;
+ nv.addGraph(function() {
+ self.d3_chart = nv.models.multiBarChart();
+
+ self.d3_chart.xAxis.tickFormat(d3.format('.2f'))
+ self.d3_chart.yAxis.tickFormat(d3.format('.1f'))
+
+ d3.select(self.options.svg_id)
+ .datum(data)
+ .call(self.d3_chart);
+
+ nv.utils.windowResize(self.d3_chart.update);
+ });
+ }
+});
+
+});
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/charts/horizontal.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/charts/horizontal.js
@@ -0,0 +1,33 @@
+// dependencies
+define(['library/utils'], function(Utils) {
+
+// widget
+return Backbone.View.extend(
+{
+ // initialize
+ initialize: function(app, options) {
+ this.app = app;
+ this.options = options;
+ this.chart = options.chart;
+ },
+
+ // render
+ refresh : function(data)
+ {
+ // add graph to screen
+ var self = this;
+ nv.addGraph(function() {
+ self.d3_chart = nv.models.multiBarHorizontalChart();
+
+ self.d3_chart.xAxis.tickFormat(function() { return ''; });
+
+ d3.select(self.options.svg_id)
+ .datum(data)
+ .call(self.d3_chart);
+
+ nv.utils.windowResize(self.d3_chart.update);
+ });
+ }
+});
+
+});
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/charts/line.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/charts/line.js
@@ -0,0 +1,39 @@
+// dependencies
+define(['library/utils'], function(Utils) {
+
+// widget
+return Backbone.View.extend(
+{
+ // initialize
+ initialize: function(app, options) {
+ this.app = app;
+ this.options = options;
+ this.chart = options.chart;
+ },
+
+ // render
+ refresh : function(data)
+ {
+ // add graph to screen
+ var self = this;
+ nv.addGraph(function() {
+ self.chart_3d = nv.models.lineChart();
+
+ self.chart_3d.xAxis
+ .tickFormat(d3.format(',f'));
+
+ self.chart_3d.yAxis
+ .tickFormat(d3.format(',.2f'));
+
+ d3.select(self.options.svg_id)
+ .datum(data)
+ .call(self.chart_3d);
+
+ nv.utils.windowResize(self.chart_3d.update);
+
+ return self.chart_3d;
+ });
+ }
+});
+
+});
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/charts/linewithfocus.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/charts/linewithfocus.js
@@ -0,0 +1,37 @@
+// dependencies
+define(['library/utils'], function(Utils) {
+
+// widget
+return Backbone.View.extend(
+{
+ // initialize
+ initialize: function(app, options) {
+ this.app = app;
+ this.options = options;
+ this.chart = options.chart;
+ },
+
+ // render
+ refresh : function(data)
+ {
+ // add graph to screen
+ var self = this;
+ nv.addGraph(function() {
+ self.chart_3d = nv.models.lineWithFocusChart();
+
+ self.chart_3d.xAxis
+ .tickFormat(d3.format(',f'));
+
+ self.chart_3d.yAxis
+ .tickFormat(d3.format(',.2f'));
+
+ d3.select(self.options.svg_id)
+ .datum(data)
+ .call(self.chart_3d);
+
+ nv.utils.windowResize(self.chart_3d.update);
+ });
+ }
+});
+
+});
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/charts/piechart.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/charts/piechart.js
@@ -0,0 +1,37 @@
+// dependencies
+define(['library/utils'], function(Utils) {
+
+// widget
+return Backbone.View.extend(
+{
+ // initialize
+ initialize: function(app, options) {
+ this.app = app;
+ this.options = options;
+ this.chart = options.chart;
+ },
+
+ // render
+ refresh : function(data)
+ {
+ // add graph to screen
+ var self = this;
+ nv.addGraph(function() {
+ self.chart_3d = nv.models.pieChart()
+ .x(function(d) { return d.key })
+ .y(function(d) { return d.y })
+ .showLabels(true);
+
+ d3.select(self.options.svg_id)
+ .datum(data)
+ .transition().duration(1200)
+ .call(self.chart_3d);
+
+ nv.utils.windowResize(self.chart_3d.update);
+
+ return self.chart_3d;
+ });
+ }
+});
+
+});
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/charts/scatterplot.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/charts/scatterplot.js
@@ -0,0 +1,37 @@
+// dependencies
+define(['library/utils'], function(Utils) {
+
+// widget
+return Backbone.View.extend(
+{
+ // initialize
+ initialize: function(app, options) {
+ this.app = app;
+ this.options = options;
+ this.chart = options.chart;
+ },
+
+ // render
+ refresh : function(data)
+ {
+ // add graph to screen
+ var self = this;
+ nv.addGraph(function() {
+ self.d3_chart = nv.models.scatterChart()
+ .showDistX(true)
+ .showDistY(true)
+ .color(d3.scale.category10().range());
+
+ self.d3_chart.xAxis.tickFormat(d3.format('.02f'))
+ self.d3_chart.yAxis.tickFormat(d3.format('.02f'))
+
+ d3.select(self.options.svg_id)
+ .datum(data)
+ .call(self.d3_chart);
+
+ nv.utils.windowResize(self.d3_chart.update);
+ });
+ }
+});
+
+});
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/charts/stackedarea.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/charts/stackedarea.js
@@ -0,0 +1,59 @@
+// dependencies
+define(['library/utils'], function(Utils) {
+
+// widget
+return Backbone.View.extend(
+{
+ // initialize
+ initialize: function(app, options) {
+ this.app = app;
+ this.options = options;
+ this.chart = options.chart;
+ },
+
+ // render
+ refresh : function(data)
+ {
+ // add graph to screen
+ var self = this;
+ nv.addGraph(function() {
+ // check data
+ var valid = true;
+ var length = 0;
+ for (var key in data) {
+ // evalute length
+ if (length == 0) {
+ length = data[key].values.length;
+ } else {
+ if (length != data[key].values.length) {
+ valid = false;
+ break;
+ }
+ }
+ }
+ if (!valid) {
+ return;
+ }
+
+ // make plot
+ self.d3_chart = nv.models.stackedAreaChart()
+ .x(function(d) {
+ return d.x
+ })
+ .y(function(d) {
+ return d.y
+ })
+ .clipEdge(true);
+
+ self.d3_chart.xAxis.tickFormat(function() { return ''; });
+
+ d3.select(self.options.svg_id)
+ .datum(data)
+ .call(self.d3_chart);
+
+ nv.utils.windowResize(self.d3_chart.update);
+ });
+ }
+});
+
+});
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/config.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/config.js
@@ -0,0 +1,219 @@
+// dependencies
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/group'],
+ function(Portlet, Table, Ui, Utils, Group) {
+
+// chart config
+return Backbone.View.extend(
+{
+ // model
+ group: new Group(),
+
+ // columns
+ columns: [],
+
+ // initialize
+ initialize: function(app, options) {
+ // link app
+ this.app = app;
+
+ // get current chart object
+ this.chart = this.app.chart;
+
+ // ui elements
+ this.message = new Ui.Message();
+ this.label = new Ui.Input({placeholder: 'Group label'});
+ this.table = new Table({content: 'No data column.'});
+
+ // add table to portlet
+ var self = this;
+ this.portlet = new Portlet({
+ icon : 'fa-edit',
+ label : 'Define group properties:',
+ operations : {
+ 'save' : new Ui.ButtonIcon({
+ icon : 'fa-save',
+ tooltip : 'Save',
+ onclick : function() {
+ // save/add group
+ self._saveGroup();
+ }
+ }),
+ 'back' : new Ui.ButtonIcon({
+ icon : 'fa-caret-left',
+ tooltip : 'Return',
+ onclick : function() {
+ self.$el.hide();
+ self.app.create.$el.show();
+ }
+ })
+ }
+ });
+ this.portlet.append(this.message.$el);
+ this.portlet.append(this.label.$el);
+ this.portlet.append(this.table.$el);
+
+ // add element
+ this.setElement(this.portlet.$el);
+
+ // change
+ var self = this;
+ this.chart.on('change:dataset_id', function() {
+ self._refreshDataset();
+ });
+ this.chart.on('change:type', function() {
+ self._refreshType();
+ });
+ this.group.on('change:label', function() {
+ self._refreshLabel();
+ });
+ this.group.on('change', function() {
+ self._refreshGroup();
+ });
+ },
+
+ // show
+ show: function() {
+ this.$el.show();
+ },
+
+ // reset
+ reset: function() {
+ this.group.reset();
+ this.group.set('id', Utils.uuid());
+ this.group.set('label', 'Group label');
+ },
+
+ // update dataset
+ _refreshDataset: function() {
+ // identify datasets
+ var dataset_id = this.chart.get('dataset_id');
+
+ // check if dataset is available
+ if (!dataset_id) {
+ return;
+ }
+
+ // get dataset
+ var dataset = this.app.datasets.get({id : dataset_id});
+
+ // check
+ if (!dataset) {
+ this.app.log('Config::render()', 'Failed to retrieve dataset.');
+ return;
+ }
+
+ // configure columns
+ this.columns = [];
+ var meta = dataset.metadata_column_types;
+ for (var key in meta){
+ this.columns.push({
+ 'label' : key + ' [' + meta[key] + ']',
+ 'value' : key
+ });
+ }
+
+ // update select fields
+ for (var key in this.list) {
+ this.list[key].update(this.columns);
+ }
+ },
+
+ // update
+ _refreshType: function() {
+ // configure chart type
+ var self = this;
+ var chart_type = this.chart.get('type');
+ if (chart_type) {
+ var chart_settings = this.app.types.get(chart_type);
+
+ // table
+ this.table.removeAll();
+ this.list = {};
+ for (var id in chart_settings.data) {
+ // create select field
+ var data_def = chart_settings.data[id];
+ var select = new Ui.Select({
+ id : 'select_' + id,
+ gid : id,
+ data : this.columns,
+ onchange : function(value) {
+ self.group.set(this.gid, value);
+ }
+ });
+
+ // add row to table
+ this.table.add(data_def.title);
+ this.table.add(select.$el);
+ this.table.append(id);
+
+ // add select field to list
+ this.list[id] = select;
+ }
+ }
+ },
+
+ // update
+ _refreshGroup: function() {
+ // update select fields
+ for (var id in this.list) {
+ var col = this.group.get(id);
+ if (col === undefined) {
+ col = 0;
+ }
+ this.list[id].value(col);
+ }
+ },
+
+ // update label
+ _refreshLabel: function() {
+ var label_text = this.group.get('label');
+ if (label_text === undefined) {
+ label_text = '';
+ }
+ this.label.value(label_text);
+ },
+
+ // create group
+ _saveGroup: function() {
+ // get current chart
+ var chart = this.chart;
+
+ // update group object
+ var group = this.group;
+ for (var key in this.list) {
+ group.set(key, this.list[key].value());
+ }
+
+ // add label
+ group.set({
+ dataset_id : this.chart.get('dataset_id'),
+ label : this.label.value(),
+ date : Utils.time()
+ });
+
+ // validate
+ if (!group.get('label')) {
+ this.message.update({message : 'Please enter a label for your group.'});
+ return;
+ }
+
+ // get groups of current chart
+ var groups = this.chart.groups;
+
+ // create/update group
+ var group_update = groups.get(group.id);
+ if (group_update) {
+ group_update.set(group.attributes);
+ } else {
+ groups.add(group.clone());
+ }
+
+ // hide
+ this.$el.hide();
+
+ // update main
+ this.app.create.$el.show();
+ }
+});
+
+});
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/create.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/create.js
@@ -0,0 +1,189 @@
+// dependencies
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils', 'models/chart', 'groups'],
+ function(Portlet, Table, Ui, Utils, Chart, Groups) {
+
+// widget
+return Backbone.View.extend(
+{
+ // defaults options
+ optionsDefault: {
+ header : true,
+ content : 'No content available.'
+ },
+
+ // current chart
+ chart : null,
+
+ // initialize
+ initialize: function(app, options)
+ {
+ // link application
+ this.app = app;
+
+ // get current chart object
+ this.chart = this.app.chart;
+
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // main elements
+ this.message = new Ui.Message();
+ this.title = new Ui.Input({placeholder: 'Chart title'});
+ this.dataset = new Ui.Input({value : app.options.dataset.id, disabled: true});
+
+ // configure dataset
+ this.groups = new Groups(this.app);
+
+ // table
+ var self = this;
+ this.table = new Table({
+ header : false,
+ onconfirm : function(type) {
+ if (self.chart.groups.length > 0) {
+ // show modal
+ self.app.modal.show({
+ title : 'Switching the chart type?',
+ body : 'You configured data sources. If you switch chart types your configurations will be removed.',
+ buttons : {
+ 'Cancel' : function() {
+ // hide modal
+ self.app.modal.hide();
+ },
+ 'Continue' : function() {
+ // hide modal
+ self.app.modal.hide();
+
+ // confirm
+ self.table.confirm(type);
+ }
+ }
+ });
+ } else {
+ // confirm
+ self.table.confirm(type);
+ }
+ },
+ onchange : function(type) {
+ // update chart type
+ self.chart.set({type: type});
+
+ // reset groups
+ self.chart.groups.reset();
+ },
+ content: 'No chart types available'
+ });
+
+ // add types
+ var types_n = 0;
+ var types = app.types.attributes;
+ for (var id in types){
+ var chart_type = types[id];
+ this.table.add (++types_n + '.');
+ this.table.add (chart_type.title);
+ this.table.append(id);
+ }
+
+ // add table to portlet
+ var self = this;
+ this.portlet = new Portlet({
+ icon : 'fa-edit',
+ label : 'Create a new chart:',
+ operations : {
+ 'save' : new Ui.ButtonIcon({
+ icon : 'fa-save',
+ tooltip : 'Save',
+ onclick : function() {
+ self._saveChart();
+ }
+ }),
+ 'back' : new Ui.ButtonIcon({
+ icon : 'fa-caret-left',
+ tooltip : 'Return',
+ onclick : function() {
+ self.$el.hide();
+ self.app.main.$el.show();
+ }
+ })
+ }
+ });
+ this.portlet.append(this.message.$el);
+ this.portlet.append((new Ui.Label({ label : 'Provide a chart title:'})).$el);
+ this.portlet.append(this.title.$el);
+ this.portlet.append((new Ui.Label({ label : 'Select a dataset:'})).$el);
+ this.portlet.append(this.dataset.$el);
+ this.portlet.append((new Ui.Label({ label : 'Select a chart type:'})).$el);
+ this.portlet.append(this.table.$el);
+ this.portlet.append(this.groups.$el);
+
+ // elements
+ this.setElement(this.portlet.$el);
+
+ // events
+ var self = this;
+ this.chart.on('change:title', function(chart) {
+ self.title.value(chart.get('title'));
+ });
+ this.chart.on('change:type', function(chart) {
+ self.table.value(chart.get('type'));
+ });
+ },
+
+ // reset
+ reset: function() {
+ this.chart.reset();
+ this.chart.set('id', Utils.uuid());
+ this.chart.set('dataset_id', app.options.dataset.id);
+ this.chart.set('type', 'bardiagram');
+ this.chart.set('title', 'Chart title');
+ },
+
+ // set chart
+ setChart: function(new_chart) {
+ this.chart.copy(new_chart);
+ },
+
+ // create chart
+ _saveChart: function() {
+ // update chart data
+ this.chart.set({
+ type : this.table.value(),
+ title : this.title.value(),
+ dataset_id : this.dataset.value(),
+ date : Utils.time()
+ });
+
+ // validate
+ if (!this.chart.get('title')) {
+ this.message.update({message : 'Please enter a title for your chart.'});
+ return;
+ }
+
+ if (!this.chart.get('type')) {
+ this.message.update({message : 'Please select a chart type.'});
+ return;
+ }
+
+ if (this.chart.groups.length == 0) {
+ this.message.update({message : 'Please configure at least one data source.'});
+ return;
+ }
+
+ // create/get chart
+ var current = this.app.charts.get(this.chart.id);
+ if (!current) {
+ current = this.chart.clone();
+ this.app.charts.add(current);
+ }
+
+ // update chart model
+ current.copy(this.chart);
+
+ // hide
+ this.$el.hide();
+
+ // update main
+ this.app.main.$el.show();
+ }
+});
+
+});
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/groups.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/groups.js
@@ -0,0 +1,154 @@
+// dependencies
+define(['library/portlet', 'library/table', 'library/ui', 'library/utils'], function(Portlet, Table, Ui, Utils) {
+
+// chart config
+return Backbone.View.extend(
+{
+ // initialize
+ initialize: function(app, options) {
+ // link app
+ this.app = app;
+
+ // get current chart object
+ this.chart = this.app.chart;
+
+ // table
+ this.table = new Table({
+ content : 'Add data sources to this table.',
+ ondblclick : function(group_id) {
+ // get group
+ var group = self.app.chart.groups.get(group_id);
+
+ // show edit
+ self.app.create.$el.hide();
+ self.app.config.show();
+ self.app.config.group.set(group.attributes);
+ }
+ });
+
+ // add table to portlet
+ var self = this;
+ this.portlet = new Portlet({
+ icon : '',
+ label : 'Configure data sources:',
+ height : 100,
+ operations : {
+ 'new' : new Ui.ButtonIcon({
+ icon : 'fa-plus',
+ tooltip: 'Create',
+ onclick: function() {
+ self.app.create.$el.hide();
+ self.app.config.show();
+ self.app.config.reset();
+ }
+ }),
+ 'edit' : new Ui.ButtonIcon({
+ icon : 'fa-pencil',
+ tooltip: 'Edit',
+ onclick: function() {
+ // check if element has been selected
+ var group_id = self.table.value();
+ if (!group_id) {
+ return;
+ }
+
+ // get group
+ var group = self.app.chart.groups.get(group_id);
+
+ // show edit
+ self.app.create.$el.hide();
+ self.app.config.show();
+ self.app.config.group.set(group.attributes);
+ }
+ }),
+ 'delete' : new Ui.ButtonIcon({
+ icon : 'fa-minus',
+ tooltip: 'Delete',
+ onclick: function() {
+ // check if element has been selected
+ var id = self.table.value();
+ if (!id) {
+ return;
+ }
+ // remove group from chart
+ self.chart.groups.remove(id);
+ }
+ })
+ }
+ });
+ this.portlet.append(this.table.$el);
+
+ // add element
+ this.setElement(this.portlet.$el);
+
+ // change
+ var self = this;
+ this.chart.on('change', function() {
+ self._refresh();
+ });
+ this.chart.on('reset', function() {
+ self._removeGroupAll();
+ });
+ this.chart.on('change:type', function() {
+ self.app.config.trigger('change');
+ });
+ this.chart.groups.on('add', function(group) {
+ self._addGroup(group);
+ });
+ this.chart.groups.on('remove', function(group) {
+ self._removeGroup(group);
+ });
+ this.chart.groups.on('reset', function(group) {
+ self._removeGroupAll();
+ });
+ this.chart.groups.on('change', function(group) {
+ self._removeGroup(group);
+ self._addGroup(group);
+ });
+ },
+
+ // refresh
+ _refresh: function() {
+ this._removeGroupAll();
+ var self = this;
+ var groups = this.chart.groups;
+ if (groups) {
+ groups.each(function(group) { self._addGroup(group); });
+ }
+ },
+
+ // add
+ _addGroup: function(group) {
+ // make custom info string
+ var info = '[';
+ var chart_type = this.chart.get('type');
+ if (chart_type) {
+ var chart_settings = this.app.types.get(chart_type);
+ for (var key in chart_settings.data) {
+ info += key + '=' + group.get(key) + ', '
+ }
+ }
+ info = info.substring(0, info.length - 2) + ']';
+
+ // add to table
+ this.table.add(group.get('label'));
+ this.table.add(info);
+ this.table.add('Last changed: ' + group.get('date'));
+ this.table.prepend(group.id);
+ this.table.value(group.id);
+ },
+
+ // remove
+ _removeGroup: function(group) {
+ // remove from to table
+ this.table.remove(group.id);
+ },
+
+ // data config reset
+ _removeGroupAll: function() {
+ // reset options table
+ this.table.removeAll();
+ }
+});
+
+});
\ No newline at end of file
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/library/portlet.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/library/portlet.js
@@ -0,0 +1,142 @@
+// dependencies
+define(['library/utils'], function(Utils) {
+
+// return
+return Backbone.View.extend(
+{
+ // visibility
+ visible: false,
+
+ // defaults options
+ optionsDefault: {
+ label : '',
+ icon : 'fa-tasks',
+ buttons : null,
+ body : null,
+ height : null,
+ operations : null,
+ placement : 'bottom',
+ overflow : 'auto'
+ },
+
+ // content
+ $content : null,
+
+ // initialize
+ initialize : function(options) {
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // create new element
+ this.setElement(this.template(this.options));
+
+ // link content
+ this.$content = this.$el.find('#content');
+
+ // set content height
+ if (this.options.height) {
+ this.$el.find('#body').css('height', this.options.height);
+ this.$el.find('#content').css('overflow', this.options.overflow);
+ }
+
+ // append buttons
+ this.$buttons = $(this.el).find('#buttons');
+ if (this.options.buttons) {
+ // link functions
+ var self = this;
+ $.each(this.options.buttons, function(name, item) {
+ self.$buttons.append(item.$el);
+ });
+ } else {
+ this.$buttons.remove();
+ }
+
+ // append operations
+ this.$operations = $(this.el).find('#operations');
+ if (this.options.operations) {
+ // link functions
+ var self = this;
+ $.each(this.options.operations, function(name, item) {
+ self.$operations.append(item.$el);
+ });
+ }
+
+ // add body
+ if(this.options.body) {
+ this.append(this.options.body);
+ }
+ },
+
+ // append
+ append: function($el) {
+ this.$content.append(Utils.wrap($el));
+ },
+
+ // content
+ content: function() {
+ return this.$content;
+ },
+
+ // hide modal
+ show: function(){
+ // fade in
+ this.$el.fadeIn('fast');
+
+ // set flag
+ this.visible = true;
+ },
+
+ // hide modal
+ hide: function(){
+ // fade out
+ this.$el.fadeOut('fast');
+
+ // set flag
+ this.visible = false;
+ },
+
+ // enable buttons
+ enableButton: function(name) {
+ this.$buttons.find('#' + String(name).toLowerCase()).prop('disabled', false);
+ },
+
+ // disable buttons
+ disableButton: function(name) {
+ this.$buttons.find('#' + String(name).toLowerCase()).prop('disabled', true);
+ },
+
+ // fill regular modal template
+ template: function(options) {
+ var tmpl = '<div class="toolForm">';
+
+ if (options.label) {
+ tmpl += '<div id="title" class="toolFormTitle" style="padding-bottom: 7px;">' +
+ '<div id="operations" style="float: right;"></div>' +
+ '<div>';
+
+ if (options.icon)
+ tmpl += '<i style="font-size: 1.2em" class="icon fa ' + options.icon + '"> </i>';
+
+ tmpl += options.label +
+ '</div>' +
+ '</div>';
+ }
+ tmpl += '<div id="body" class="toolFormBody">';
+
+ if (options.placement == 'top') {
+ tmpl += '<div id="buttons" class="buttons" style="height: 50px; padding: 10px;"></div>';
+ }
+
+ tmpl += '<div id="content" class="content" style="height: inherit; padding: 10px;"></div>';
+
+ if (options.placement == 'bottom') {
+ tmpl += '<div id="buttons" class="buttons" style="height: 50px; padding: 10px;"></div>';
+ }
+
+ tmpl += '</div>' +
+ '</div>';
+ return tmpl;
+ }
+});
+
+});
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/library/table.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/library/table.js
@@ -0,0 +1,188 @@
+// dependencies
+define(['library/utils'], function(Utils) {
+
+// return
+return Backbone.View.extend(
+{
+ // current row
+ row: null,
+
+ // count rows
+ row_count: 0,
+
+ // defaults options
+ optionsDefault: {
+ content : 'No content available.',
+ onchange : null,
+ ondblclick : null,
+ onconfirm : null
+ },
+
+ // events
+ events : {
+ 'click' : 'onclick',
+ 'dblclick' : 'ondblclick'
+ },
+
+ // first
+ first: true,
+
+ // initialize
+ initialize : function(options) {
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // create new element
+ this.setElement(this.template(options));
+
+ // initialize row
+ this.row = $('<tr></tr>');
+ },
+
+ // add header cell
+ addHeader: function($el) {
+ var wrapper = $('<th></th>');
+ wrapper.append($el);
+ this.row.append(wrapper);
+ },
+
+ // header
+ appendHeader: function() {
+ // append header row
+ $(this.el).find('thead').append(this.row);
+
+ // row
+ this.row = $('<tr></tr>');
+ },
+
+ // add row cell
+ add: function($el) {
+ var wrapper = $('<td></td>');
+ wrapper.append($el);
+ this.row.append(wrapper);
+ },
+
+ // append
+ append: function(id) {
+ this.commit(id);
+ },
+
+ // prepend
+ prepend: function(id) {
+ this.commit(id, true);
+ },
+
+ // commit
+ commit: function(id, prepend) {
+ // add
+ this.row.attr('id', id);
+
+ // add row
+ if (prepend) {
+ $(this.el).find('tbody').prepend(this.row);
+ } else {
+ $(this.el).find('tbody').append(this.row);
+ }
+
+ // row
+ this.row = $('<tr></tr>');
+
+ // row count
+ this.row_count++;
+ this.refresh();
+ },
+
+ // remove
+ remove: function(id) {
+ $(this.el).find('#' + id).remove();
+ this.row_count--;
+ this.refresh();
+ },
+
+ // remove
+ removeAll: function() {
+ $(this.el).find('tbody').html('');
+ this.row_count = 0;
+ this.refresh();
+ },
+
+ // value
+ value: function(new_value) {
+ // get current id/value
+ this.before = this.$el.find('.current').attr('id');
+
+ // check if new_value is defined
+ if (new_value !== undefined) {
+ this.$el.find('tr').removeClass('current');
+ if (new_value) {
+ this.$el.find('#' + new_value).addClass('current');
+ }
+ }
+
+ // get current id/value
+ var after = this.$el.find('.current').attr('id');
+ if(after === undefined) {
+ return null;
+ } else {
+ // fire onchange
+ if (after != this.before && this.options.onchange) {
+ this.options.onchange(new_value);
+ }
+
+ // return current value
+ return after;
+ }
+ },
+
+ // confirm new value
+ confirm: function(new_value) {
+ this.value(new_value);
+ },
+
+ // onclick
+ onclick: function(e) {
+ // get values
+ var old_value = this.value();
+ var new_value = $(e.target).closest('tr').attr('id');
+
+ // check equality
+ if (new_value && old_value != new_value) {
+ if (this.options.onconfirm) {
+ this.options.onconfirm(new_value);
+ } else {
+ this.confirm(new_value);
+ }
+ }
+ },
+
+ // onclick
+ ondblclick: function(e) {
+ var value = this.value();
+ if (value && this.options.ondblclick) {
+ this.options.ondblclick(value);
+ }
+ },
+
+ // refresh
+ refresh: function() {
+ if (this.row_count == 0) {
+ this.$el.find('tmessage').show();
+ } else {
+ this.$el.find('tmessage').hide();
+ }
+ },
+
+ // load html template
+ template: function(options)
+ {
+ return '<div>' +
+ '<table class="grid">' +
+ '<thead></thead>' +
+ '<tbody style="cursor: pointer;"></tbody>' +
+ '</table>' +
+ '<tmessage>' + options.content + '</tmessage>' +
+ '<div>';
+ }
+});
+
+});
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/library/ui.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/library/ui.js
@@ -0,0 +1,472 @@
+// dependencies
+define(['library/utils', 'library/ui.select'], function(Utils, Select) {
+
+// plugin
+var Label = Backbone.View.extend(
+{
+ // options
+ optionsDefault: {
+ label : ''
+ },
+
+ // initialize
+ initialize : function(options) {
+ // get options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // create new element
+ this.setElement(this.template(this.options));
+ },
+
+ // template
+ template: function(options) {
+ return '<label><b>' + options.label + '</b></label>';
+ },
+
+ // value
+ value: function() {
+ return options.label;
+ }
+});
+
+// plugin
+var Button = Backbone.View.extend(
+{
+ // options
+ optionsDefault: {
+ label : '',
+ float : 'right',
+ cls : 'btn-default',
+ type : 'submit',
+ icon : ''
+ },
+
+ // initialize
+ initialize : function(options) {
+ // get options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // create new element
+ this.setElement(this.template(this.options));
+
+ // add event
+ $(this.el).on('click', options.onclick);
+ },
+
+ // element
+ template: function(options) {
+ var str = '<button type="' + options.type + '" style="margin-right: 5px; float: ' + options.float + ';" type="button" class="btn ' + options.cls + '">';
+ if (options.icon) {
+ str += '<i class="icon fa ' + options.icon + '"></i> ' ;
+ }
+ str += options.label +
+ '</button>';
+ return str;
+ }
+});
+
+// plugin
+var Anchor = Backbone.View.extend(
+{
+ // options
+ optionsDefault: {
+ label : ''
+ },
+
+ // initialize
+ initialize : function(options) {
+ // get options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // create new element
+ this.setElement(this.template(this.options));
+
+ // add event
+ $(this.el).on('click', options.onclick);
+ },
+
+ // element
+ template: function(options) {
+ return '<div><a href="javascript:void(0)">' + options.label + '</a></div>';
+ }
+});
+
+// plugin
+var Message = Backbone.View.extend(
+{
+ // options
+ optionsDefault: {
+ message : '',
+ status : 'info',
+ persistent : false
+ },
+
+ // initialize
+ initialize : function(options) {
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // create new element
+ this.setElement('<div></div>');
+ },
+
+ // update
+ update : function(options) {
+ // get options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // show message
+ if (options.message != '') {
+ this.$el.html(this.template(this.options));
+ this.$el.fadeIn();
+
+ // check if message is persistent
+ if (!options.persistent) {
+ // set timer
+ var self = this;
+ window.setTimeout(function() {
+ if (self.$el.is(':visible')) {
+ self.$el.fadeOut();
+ } else {
+ self.$el.hide();
+ }
+ }, 3000);
+ }
+ } else {
+ this.$el.fadeOut();
+ }
+ },
+
+ // element
+ template: function(options) {
+ return '<div class="alert alert-' + options.status + '" style="padding: 2px 2px 2px 10px;">' + options.message + '</div>';
+ }
+});
+
+// plugin
+var Searchbox = Backbone.View.extend(
+{
+ // options
+ optionsDefault: {
+ onclick : null,
+ searchword : ''
+ },
+
+ // initialize
+ initialize : function(options) {
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // create new element
+ this.setElement(this.template(this.options));
+
+ // add click event
+ var self = this;
+ if (this.options.onclick) {
+ this.$el.on('submit', function(e) {
+ var search_field = self.$el.find('#search');
+ self.options.onclick(search_field.val());
+ });
+ }
+ },
+
+ // element
+ template: function(options) {
+ return '<div class="search">' +
+ '<form onsubmit="return false;">' +
+ '<input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="' + options.searchword + '">' +
+ '<button type="submit" class="btn search-btn">' +
+ '<i class="fa fa-search"></i>' +
+ '</button>' +
+ '</form>' +
+ '</div>';
+ }
+});
+
+// plugin
+var Title = Backbone.View.extend(
+{
+ // options
+ optionsDefault: {
+ label : 'Unlabeled',
+ body : null
+ },
+
+ // initialize
+ initialize : function(options) {
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // create new element
+ this.setElement(this.template(this.options));
+
+ if (this.options.body) {
+ this.$el.find('.body').append(this.options.body);
+ }
+ },
+
+ // element
+ template: function(options) {
+ return '<div id="title" class="title">' +
+ options.label + ':' +
+ '</div>';
+ }
+});
+
+// tab
+var ButtonMenu = Backbone.View.extend(
+{
+ // main options
+ options:
+ {
+ id : '',
+ title : '',
+ target : '',
+ href : '',
+ onunload : null,
+ onclick : null,
+ visible : true,
+ icon : null,
+ tag : ''
+ },
+
+ // optional sub menu
+ $menu: null,
+
+ // initialize
+ initialize: function (options)
+ {
+ // read in defaults
+ if (options)
+ this.options = _.defaults(options, this.options);
+
+ // add template for tab
+ this.setElement($(this._template(this.options)));
+
+ // find root
+ var $root = $(this.el).find('.root');
+
+ // link head
+ var self = this;
+ $root.on('click', function(e)
+ {
+ // prevent default
+ e.preventDefault();
+
+ // add click event
+ if(self.options.onclick) {
+ self.options.onclick();
+ }
+ });
+
+ // visiblity
+ if (!this.options.visible)
+ this.hide();
+ },
+
+ // show
+ show: function()
+ {
+ $(this.el).show();
+ },
+
+ // hide
+ hide: function()
+ {
+ $(this.el).hide();
+ },
+
+ // add menu item
+ addMenu: function (options)
+ {
+ // menu option defaults
+ var menuOptions = {
+ title : '',
+ target : '',
+ href : '',
+ onclick : null,
+ divider : false,
+ icon : null
+ }
+
+ // read in defaults
+ if (options)
+ menuOptions = _.defaults(options, menuOptions);
+
+ // check if submenu element is available
+ if (!this.$menu)
+ {
+ // insert submenu element into root
+ $(this.el).append(this._templateMenu());
+
+ // update element link
+ this.$menu = $(this.el).find('.menu');
+ }
+
+ // create
+ var $item = $(this._templateMenuItem(menuOptions));
+
+ // add events
+ $item.on('click', function(e)
+ {
+ // prevent default
+ e.preventDefault();
+
+ // add click event
+ if(menuOptions.onclick) {
+ menuOptions.onclick();
+ }
+ });
+
+ // append menu
+ this.$menu.append($item);
+
+ // append divider
+ if (menuOptions.divider)
+ this.$menu.append($(this._templateDivider()));
+ },
+
+ // fill template header
+ _templateMenuItem: function (options)
+ {
+ var tmpl = '<li>' +
+ '<a href="' + options.href + '" target="' + options.target + '">';
+
+ if (options.icon)
+ tmpl += '<i class="fa ' + options.icon + '"></i>';
+
+ tmpl += ' ' + options.title +
+ '</a>' +
+ '</li>';
+ return tmpl;
+ },
+
+ // fill template header
+ _templateMenu: function ()
+ {
+ return '<ul class="menu dropdown-menu pull-right" role="menu"></ul>';
+ },
+
+ _templateDivider: function()
+ {
+ return '<li class="divider"></li>';
+ },
+
+ // fill template
+ _template: function (options)
+ {
+ // start template
+ var tmpl = '<div id="' + options.id + '" class="button-menu btn-group">' +
+ '<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';
+
+ if (options.icon)
+ tmpl += '<i class="fa ' + options.icon + '"></i>';
+
+ '</button>' +
+ '</div>';
+
+ // return template
+ return tmpl;
+ }
+});
+
+// plugin
+var ButtonIcon = Backbone.View.extend(
+{
+ // options
+ optionsDefault: {
+ label : '',
+ float : 'right',
+ cls : 'icon-btn',
+ type : 'submit',
+ icon : '',
+ tooltip : ''
+ },
+
+ // initialize
+ initialize : function(options) {
+ // get options
+ if (options)
+ this.options = _.defaults(options, this.optionsDefault);
+ else
+ this.options = this.optionsDefault;
+
+ // create new element
+ this.setElement(this.template(this.options));
+
+ // add event
+ $(this.el).on('click', options.onclick);
+
+ // add tooltip
+ $(this.el).tooltip({title: options.tooltip, placement: 'bottom'});
+ },
+
+ // element
+ template: function(options) {
+ var str = '<a style="margin-right: 5px; float: ' + options.float + ';" class="' + options.cls + '">';
+ if (options.icon) {
+ str += '<i class="icon fa ' + options.icon + '"></i>';
+ }
+ str += options.label +
+ '</a>';
+ return str;
+ }
+});
+
+
+// plugin
+var Input = Backbone.View.extend(
+{
+ // options
+ optionsDefault: {
+ value : '',
+ type : 'text',
+ placeholder : '',
+ disabled : false
+ },
+
+ // initialize
+ initialize : function(options) {
+ // get options
+ if (options)
+ this.options = _.defaults(options, this.optionsDefault);
+ else
+ this.options = this.optionsDefault;
+
+ // create new element
+ this.setElement(this.template(this.options));
+
+ // disable input field
+ if (this.options.disabled) {
+ this.$el.prop('disabled', true);
+ }
+ },
+
+ // value
+ value : function (new_val) {
+ if (new_val !== undefined) {
+ this.$el.val(new_val);
+ }
+ return this.$el.val();
+ },
+
+ // element
+ template: function(options) {
+ return '<input id="' + options.id + '" type="' + options.type + '" value="' + options.value + '" placeholder="' + options.placeholder + '" class="form-control">';
+ }
+});
+
+// return
+return {
+ Label : Label,
+ Button : Button,
+ ButtonIcon : ButtonIcon,
+ Input : Input,
+ Anchor : Anchor,
+ Message : Message,
+ Searchbox : Searchbox,
+ Title : Title,
+ Select : Select,
+ ButtonMenu : ButtonMenu
+}
+});
diff -r e30627f8eac5e1db3d58b654aa59f14834c399e8 -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d config/plugins/visualizations/charts/static/library/ui.select.js
--- /dev/null
+++ b/config/plugins/visualizations/charts/static/library/ui.select.js
@@ -0,0 +1,117 @@
+// dependencies
+define(['library/utils'], function(Utils) {
+
+
+// plugin
+return Backbone.View.extend(
+{
+ // options
+ optionsDefault: {
+ id : '',
+ cls : ''
+ },
+
+ // initialize
+ initialize : function(options) {
+ // configure options
+ this.options = Utils.merge(options, this.optionsDefault);
+
+ // create new element
+ this.setElement(this.template(this.options));
+
+ // add change event
+ var self = this;
+ if (this.options.onchange) {
+ this.$el.on('change', function() { self.options.onchange(self.value()) });
+ }
+ },
+
+ // value
+ value : function (new_val) {
+ if (new_val !== undefined) {
+ this.$el.val(new_val);
+ }
+ return this.$el.val();
+ },
+
+ // label
+ label : function () {
+ return this.$el.find('option:selected').text();
+ },
+
+ // disabled
+ disabled: function() {
+ return this.$el.is(':disabled');
+ },
+
+ // render
+ update: function(options) {
+ // selected
+ var selected = this.$el.val();
+
+ // remove all options
+ $(this.el).find('option').remove();
+
+ // add new options
+ for (var key in options.data) {
+ $(this.el).append(this.templateOption(options.data[key]));
+ }
+
+ // check if selected value exists
+ var exists = 0 != $(this.el).find('option[value=' + selected + ']').length;
+
+ // add selected value
+ if (exists)
+ $(this.el).val(selected);
+ },
+
+ // update from url
+ updateUrl : function(options, callback) {
+ // get json
+ var self = this;
+ Utils.get(options.url, function(json) {
+ // write data into array
+ var data = [];
+ for (key in json) {
+ data.push({label: json[key].name, value: json[key].id});
+ }
+
+ // check if disabled. do not update disabled select elements.
+ if (!self.disabled()) {
+ self.update({data: data});
+ }
+
+ // callback
+ if (callback) {
+ callback();
+ }
+ });
+ },
+
+ // option
+ templateOption: function(options) {
+ return '<option value="' + options.value + '">' + options.label + '</option>';
+ },
+
+ // element
+ template: function(options) {
+ var tmpl = '<select id="' + options.id + '" class="select ' + options.cls + ' ' + options.id + '">';
+ for (key in options.data) {
+ // options
+ var item = options.data[key];
+
+ // identify selected value
+ var tag = '';
+ if (item.value == options.selected || item.value == '') {
+ tag = 'selected';
+ }
+
+ // add template string
+ tmpl += '<option value="' + item.value + '" ' + tag + '>' + item.label + '</option>';
+ }
+ tmpl += '</select>';
+ return tmpl;
+ }
+});
+
+});
This diff is so big that we needed to truncate the remainder.
https://bitbucket.org/galaxy/galaxy-central/commits/2113355e2eb0/
Changeset: 2113355e2eb0
Branch: search
User: kellrott
Date: 2014-01-14 17:27:10
Summary: Adding update_time to ldda to_dict
Affected #: 1 file
diff -r 4e2f60de42fa5a00251bdf0d4e17edb2c9a9710d -r 2113355e2eb0fc2b2c34300bf9b117b6105780d2 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -2217,6 +2217,7 @@
library_dataset_id = ldda.library_dataset_id,
file_size = file_size,
file_name = ldda.file_name,
+ update_time = ldda.update_time.isoformat(),
data_type = ldda.ext,
genome_build = ldda.dbkey,
misc_info = ldda.info,
https://bitbucket.org/galaxy/galaxy-central/commits/985e3d88f9ac/
Changeset: 985e3d88f9ac
Branch: search
User: kellrott
Date: 2014-01-14 19:35:43
Summary: Adding update_time to hda to_dict
Affected #: 1 file
diff -r 2113355e2eb0fc2b2c34300bf9b117b6105780d2 -r 985e3d88f9ac85a90de7aa541b5844037cccd120 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -1779,6 +1779,7 @@
visible = hda.visible,
state = hda.state,
file_size = int( hda.get_size() ),
+ update_time = hda.update_time.isoformat(),
data_type = hda.ext,
genome_build = hda.dbkey,
misc_info = hda.info,
https://bitbucket.org/galaxy/galaxy-central/commits/29bb29e0b3f9/
Changeset: 29bb29e0b3f9
User: jmchilton
Date: 2014-01-16 04:59:36
Summary: Merged in kellrott/galaxy-central/search (pull request #296)
Adding update_time to dataset to_dict methods
Affected #: 1 file
diff -r c28f10187bb86e0f18d36c1a7086af8615c87c97 -r 29bb29e0b3f9004304896403d15a09482d8e3c03 lib/galaxy/model/__init__.py
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -1779,6 +1779,7 @@
visible = hda.visible,
state = hda.state,
file_size = int( hda.get_size() ),
+ update_time = hda.update_time.isoformat(),
data_type = hda.ext,
genome_build = hda.dbkey,
misc_info = hda.info,
@@ -2217,6 +2218,7 @@
library_dataset_id = ldda.library_dataset_id,
file_size = file_size,
file_name = ldda.file_name,
+ update_time = ldda.update_time.isoformat(),
data_type = ldda.ext,
genome_build = ldda.dbkey,
misc_info = ldda.info,
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0
commit/galaxy-central: martenson: javascript library and modal refactoring, automatic even binding if flag provided
by commits-noreply@bitbucket.org 16 Jan '14
by commits-noreply@bitbucket.org 16 Jan '14
16 Jan '14
1 new commit in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/c28f10187bb8/
Changeset: c28f10187bb8
User: martenson
Date: 2014-01-16 00:11:09
Summary: javascript library and modal refactoring, automatic even binding if flag provided
Affected #: 5 files
diff -r 9fe1a6fc375b3fad14dac271ed8f85e02fc6ef6d -r c28f10187bb86e0f18d36c1a7086af8615c87c97 lib/galaxy/webapps/galaxy/api/lda_datasets.py
--- a/lib/galaxy/webapps/galaxy/api/lda_datasets.py
+++ b/lib/galaxy/webapps/galaxy/api/lda_datasets.py
@@ -14,9 +14,9 @@
import urllib2
import zipfile
from paste.httpexceptions import HTTPBadRequest
+from galaxy import util, web
from galaxy.exceptions import ItemAccessibilityException, MessageException, ItemDeletionException, ObjectNotFound
from galaxy.security import Action
-from galaxy import util, web
from galaxy.util.streamball import StreamBall
from galaxy.web.base.controller import BaseAPIController, UsesVisualizationMixin
@@ -39,14 +39,12 @@
:returns: detailed dataset information from base controller
.. seealso:: :attr:`galaxy.web.base.controller.UsesLibraryMixinItems.get_library_dataset`
"""
- # Get dataset.
try:
dataset = self.get_library_dataset( trans, id = id, check_ownership=False, check_accessible=True )
except Exception, e:
trans.response.status = 500
return str( e )
try:
- # Default: return dataset as dict.
rval = dataset.to_dict()
except Exception, e:
rval = "Error in dataset API at listing contents: " + str( e )
diff -r 9fe1a6fc375b3fad14dac271ed8f85e02fc6ef6d -r c28f10187bb86e0f18d36c1a7086af8615c87c97 static/scripts/galaxy.library.js
--- a/static/scripts/galaxy.library.js
+++ b/static/scripts/galaxy.library.js
@@ -122,7 +122,7 @@
// CONTAINER
tmpl_array.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');
- tmpl_array.push('<h3>New Data Libraries. This is work in progress. Report problems & ideas to <a href="mailto:marten@bx.psu.edu?Subject=DataLibraries_Feedback" target="_blank">Marten</a>.</h3>');
+ tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
// TOOLBAR
tmpl_array.push('<div id="library_folder_toolbar" >');
@@ -457,6 +457,7 @@
var self = this;
this.modal = new mod_modal.GalaxyModal({
destructible : true,
+ bindClosingEvents: true,
title : 'Dataset Details',
body : template,
buttons : {
@@ -477,7 +478,6 @@
$(this.modal.elMain).find('#dataset_import_single').val(self.lastSelectedHistory);
}
}
- this.modal.bindEvents();
this.modal.show();
},
@@ -614,6 +614,7 @@
var history_modal_tmpl = _.template(self.templateBulkImportInModal(), {histories : histories.models});
self.modal = new mod_modal.GalaxyModal({
destructible : true,
+ bindClosingEvents: true,
title : 'Import into History',
body : history_modal_tmpl,
buttons : {
@@ -621,7 +622,6 @@
'Close' : function() {self.modal.hideOrDestroy();}
}
});
- self.modal.bindEvents();
self.modal.show();
},
error: function(){
@@ -724,6 +724,7 @@
//send request
$('<form action="'+ url +'" method="'+ (method||'post') +'">'+inputs+'</form>')
.appendTo('body').submit().remove();
+
mod_toastr.info('Your download will begin soon');
};
},
@@ -737,6 +738,7 @@
var self = this;
this.modal = new mod_modal.GalaxyModal({
destructible : true,
+ bindClosingEvents: true,
title : 'Create New Folder',
body : this.templateNewFolderInModal(),
buttons : {
@@ -744,7 +746,6 @@
'Close' : function() {self.modal.hideOrDestroy(); self.modal = null;}
}
});
- this.modal.bindEvents();
this.modal.show();
},
@@ -810,7 +811,7 @@
tmpl_array = [];
tmpl_array.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; overflow: auto !important; ">');
tmpl_array.push('');
- tmpl_array.push('<h3>New Data Libraries. This is work in progress. Report problems & ideas to <a href="mailto:marten@bx.psu.edu?Subject=DataLibraries_Feedback" target="_blank">Marten</a>.</h3>');
+ tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');
tmpl_array.push('<a href="" id="create_new_library_btn" class="btn btn-primary file ">New Library</a>');
tmpl_array.push('<table class="table table-condensed">');
tmpl_array.push(' <thead>');
@@ -866,7 +867,7 @@
},
error: function(model, response){
if (response.statusCode().status === 403){
- mod_toastr.error('Please log in first. Redirecting to login page in 3s.');
+ mod_toastr.info('Please log in first. Redirecting to login page in 3s.');
setTimeout(that.redirectToLogin, 3000);
} else {
mod_toastr.error('An error occured. Please try again.');
@@ -894,6 +895,7 @@
var self = this;
this.modal = new mod_modal.GalaxyModal({
destructible : true,
+ bindClosingEvents: true,
title : 'Create New Library',
body : this.templateNewLibraryInModal(),
buttons : {
@@ -901,7 +903,6 @@
'Close' : function() {self.modal.hideOrDestroy();}
}
});
- this.modal.bindEvents();
this.modal.show();
},
diff -r 9fe1a6fc375b3fad14dac271ed8f85e02fc6ef6d -r c28f10187bb86e0f18d36c1a7086af8615c87c97 static/scripts/galaxy.modal.js
--- a/static/scripts/galaxy.modal.js
+++ b/static/scripts/galaxy.modal.js
@@ -16,50 +16,72 @@
height : null,
width : null
},
+
+ // flag whether the closing events are bound
+ eventsBound: false,
// options
options : {
// by default the modal cannot be removed by the self.destroy() method
// but only hidden through self.hide()
- destructible: false
+ destructible: false,
+ // by default don't bind the events
+ bindClosingEvents: false
},
// initialize
initialize : function(options) {
self = this;
- if (options)
+ if (options){
this.create(options);
+ }
},
hideOrDestroy: function(){
- if (this.options.destructible){
- self.destroy();
+ self.visible = false;
+
+ //unbinds event for ALL modals?
+ self.unbindEvents();
+
+ if (self.options.destructible){
+ self.$el.remove(); // destroy
} else {
self.hide();
}
},
+ // hide modal, shouldn't be called directly but through hideOrDestroy()
+ // however hide() remains for backwards compatibility
+ hide: function(){
+ this.visible = false;
+ this.$el.fadeOut('fast');
+ },
+
// bind the click-to-hide function
bindEvents: function() {
// bind the ESC key to hideOrDestroy() function
$(document).on('keyup', function(event){
- if (event.keyCode == 27) { self.hideOrDestroy() }
+ if (event.keyCode == 27) {
+ self.hideOrDestroy()
+ }
})
// bind the 'click anywhere' to hideOrDestroy() function...
- $('html').on('click', function(event){
- self.hideOrDestroy()
- })
+ $('html').on('click', self.hideOrDestroy)
// ...but don't hide if the click is on modal content
$('.modal-content').on('click', function(event){
event.stopPropagation();
})
+
+ self.eventsBound = true;
},
// unbind the click-to-hide function
unbindEvents: function(){
// unbind the ESC key to hideOrDestroy() function
$(document).off('keyup', function(event){
- if (event.keyCode == 27) { self.hideOrDestroy() }
+ if (event.keyCode == 27) {
+ self.hideOrDestroy()
+ }
})
// unbind the 'click anywhere' to hideOrDestroy() function...
$('html').off('click', function(event){
@@ -68,6 +90,8 @@
$('.modal-content').off('click', function(event){
event.stopPropagation();
})
+
+ self.eventsBound = false;
},
// adds and displays a new frame/window
@@ -76,59 +100,43 @@
this.initialize(options);
// fix height
- if (this.options.height)
- {
+ if (this.options.height){
this.$body.css('height', this.options.height);
this.$body.css('overflow', 'hidden');
- } else
+ } else{
this.$body.css('max-height', $(window).height() / 2);
+ }
// fix width
- if (this.options.width)
+ if (this.options.width){
this.$dialog.css('width', this.options.width);
+ }
// show
- if (this.visible)
+ if (this.visible){
this.$el.show();
- else
+ } else {
this.$el.fadeIn('fast');
+ }
// set flag
this.visible = true;
},
- // hide modal, shouldn't be called directly but through hideOrDestroy()
- hide: function(){
- // fade out
- this.$el.fadeOut('fast');
- // set flag
- this.visible = false;
- // unbind events
- this.unbindEvents();
- },
-
- // destroy modal, shouldn't be called directly but through hideOrDestroy()
- destroy: function(){
- // set flag
- this.visible = false;
- // unbind events
- this.unbindEvents();
- // remove
- this.$el.remove();
- },
-
// create
create: function(options) {
// configure options
this.options = _.defaults(options, this.optionsDefault);
// check for progress bar request
- if (this.options.body == 'progress')
+ if (this.options.body == 'progress'){
this.options.body = $('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>');
+ }
// remove former element
- if (this.$el)
+ if (this.$el){
this.$el.remove();
+ }
// create new element
this.setElement(this.template(this.options.title));
@@ -144,8 +152,9 @@
this.$body.html(this.options.body);
// configure background
- if (!this.options.backdrop)
+ if (!this.options.backdrop){
this.$backdrop.removeClass('in');
+ }
// append buttons
if (this.options.buttons) {
@@ -160,6 +169,10 @@
// append to main element
$(this.elMain).append($(this.el));
+
+ if (this.options.bindClosingEvents && !this.eventsBound){
+ this.bindEvents();
+ }
},
// enable buttons
diff -r 9fe1a6fc375b3fad14dac271ed8f85e02fc6ef6d -r c28f10187bb86e0f18d36c1a7086af8615c87c97 static/scripts/packed/galaxy.library.js
--- a/static/scripts/packed/galaxy.library.js
+++ b/static/scripts/packed/galaxy.library.js
@@ -1,1 +1,1 @@
-var view=null;var library_router=null;var responses=[];define(["galaxy.modal","galaxy.masthead","utils/galaxy.utils","libs/toastr"],function(k,l,h,n){var f=Backbone.Model.extend({urlRoot:"/api/libraries"});var c=Backbone.Model.extend({urlRoot:"/api/folders"});var o=Backbone.Collection.extend({url:"/api/libraries",model:f});var i=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var d=Backbone.Collection.extend({model:i});var e=Backbone.Model.extend({defaults:{folder:new d(),full_path:"unknown",urlRoot:"/api/folders/",id:"unknown"},parse:function(r){this.full_path=r[0].full_path;this.get("folder").reset(r[1].folder_contents);return r}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var j=Backbone.Model.extend({url:"/api/histories/"});var p=Backbone.Collection.extend({url:"/api/histories",model:j});var q=Backbone.Router.extend({routes:{"":"libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var m=Backbone.View.extend({el:"#center",progress:0,progressStep:1,lastSelectedHistory:"",modal:null,folders:null,initialize:function(){this.folders=[];this.queue=jQuery.Deferred();this.queue.resolve()},templateFolder:function(){var r=[];r.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');r.push('<h3>New Data Libraries. This is work in progress. Report problems & ideas to <a href="mailto:marten@bx.psu.edu?Subject=DataLibraries_Feedback" target="_blank">Marten</a>.</h3>');r.push('<div id="library_folder_toolbar" >');r.push(' <button title="Create New Folder" id="toolbtn_create_folder" class="btn btn-primary" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');r.push(' <button id="toolbtn_bulk_import" class="btn btn-primary" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-external-link"></span> to history</button>');r.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');r.push(' <button id="drop_toggle" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">');r.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');r.push(" </button>");r.push(' <ul class="dropdown-menu" role="menu">');r.push(' <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');r.push(" </ul>");r.push(" </div>");r.push("</div>");r.push('<div class="library_breadcrumb">');r.push('<a title="Return to the list of libraries" href="#">Libraries</a><b>|</b> ');r.push("<% _.each(path, function(path_item) { %>");r.push("<% if (path_item[0] != id) { %>");r.push('<a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a><b>|</b> ');r.push("<% } else { %>");r.push('<span title="You are in this folder"><%- path_item[1] %></span>');r.push("<% } %>");r.push("<% }); %>");r.push("</div>");r.push('<table id="folder_table" class="table table-condensed">');r.push(" <thead>");r.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');r.push(' <th class="button_heading">view</th>');r.push(" <th>name</th>");r.push(" <th>data type</th>");r.push(" <th>size</th>");r.push(" <th>date (UTC)</th>");r.push(" </thead>");r.push(" <tbody>");r.push(" <td></td>");r.push(' <td><button title="Go to parent folder" type="button" data-id="<%- upper_folder_id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-arrow-up"></span> .. go up</td>');r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" </tr>");r.push(" <% _.each(items, function(content_item) { %>");r.push(' <tr class="folder_row light" id="<%- content_item.id %>">');r.push(' <% if (content_item.get("type") === "folder") { %>');r.push(" <td></td>");r.push(' <td><button title="Open this folder" type="button" data-id="<%- content_item.id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-folder-open"></span> browse</td>');r.push(' <td><%- content_item.get("name") %>');r.push(' <% if (content_item.get("item_count") === 0) { %>');r.push(' <span class="muted">(empty folder)</span>');r.push(" <% } %>");r.push(" </td>");r.push(" <td>folder</td>");r.push(' <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>');r.push(" <% } else { %>");r.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');r.push(" <td>");r.push(' <button title="See details of this dataset" type="button" class="library-dataset btn btn-default btn-xs">');r.push(' <span class="fa fa-eye"></span> details');r.push(" </button>");r.push(" </td>");r.push(' <td><%- content_item.get("name") %></td>');r.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');r.push(' <td><%= _.escape(content_item.get("readable_size")) %></td>');r.push(" <% } %> ");r.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>');r.push(" </tr>");r.push(" <% }); %>");r.push(" ");r.push(" </tbody>");r.push("</table>");r.push("</div>");return r.join("")},templateDatasetModal:function(){var r=[];r.push('<div id="dataset_info_modal">');r.push(' <table class="table table-striped table-condensed">');r.push(" <tr>");r.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');r.push(' <td><%= _.escape(item.get("name")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Data type</th>');r.push(' <td><%= _.escape(item.get("data_type")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Genome build</th>');r.push(' <td><%= _.escape(item.get("genome_build")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Size</th>');r.push(" <td><%= _.escape(size) %></td>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Date uploaded (UTC)</th>');r.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Uploaded by</th>');r.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');r.push(" </tr>");r.push(' <tr scope="row">');r.push(' <th scope="row">Data Lines</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Comment Lines</th>');r.push(' <% if (item.get("metadata_comment_lines") === "") { %>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');r.push(" <% } else { %>");r.push(' <td scope="row">unknown</td>');r.push(" <% } %>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Number of Columns</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Column Types</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Miscellaneous information</th>');r.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');r.push(" </tr>");r.push(" </table>");r.push(' <pre class="peek">');r.push(" </pre>");r.push("</div>");return r.join("")},templateHistorySelectInModal:function(){var r=[];r.push('<span id="history_modal_combo" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateBulkImportInModal:function(){var r=[];r.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateProgressBar:function(){var r=[];r.push('<div class="import_text">');r.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");r.push("</div>");r.push('<div class="progress">');r.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');r.push(' <span class="completion_span">0% Complete</span>');r.push(" </div>");r.push("</div>");r.push("");return r.join("")},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return tmpl_array.join("")},events:{"click #select-all-checkboxes":"selectAll","click .folder_row":"selectClickedRow","click #toolbtn_bulk_import":"modalBulkImport","click #toolbtn_dl":"bulkDownload","click .library-dataset":"showDatasetDetails","click #toolbtn_create_folder":"createFolderFromModal","click .btn_open_folder":"navigateToFolder"},render:function(r){$("#center").css("overflow","auto");view=this;var t=this;var s=new e({id:r.id});s.url=s.attributes.urlRoot+r.id+"/contents";s.fetch({success:function(u){for(var w=0;w<s.attributes.folder.models.length;w++){var v=s.attributes.folder.models[w];if(v.get("type")==="file"){v.set("readable_size",t.size_to_string(v.get("file_size")))}}var y=s.full_path;var z;if(y.length===1){z=0}else{z=y[y.length-2][0]}var x=_.template(t.templateFolder(),{path:s.full_path,items:s.attributes.folder.models,id:r.id,upper_folder_id:z});t.$el.html(x)},error:function(){n.error("An error occured :(")}})},size_to_string:function(r){var s="";if(r>=100000000000){r=r/100000000000;s="TB"}else{if(r>=100000000){r=r/100000000;s="GB"}else{if(r>=100000){r=r/100000;s="MB"}else{if(r>=100){r=r/100;s="KB"}else{r=r*10;s="b"}}}}return(Math.round(r)/10)+s},navigateToFolder:function(s){var r=$(s.target).attr("data-id");if(typeof r==="undefined"){return false}else{if(r==="0"){library_router.navigate("#",{trigger:true,replace:true})}else{library_router.navigate("folders/"+r,{trigger:true,replace:true})}}},showDatasetDetails:function(u){u.preventDefault();var v=$(u.target).parent().parent().attr("id");var t=new i();var s=new p();t.id=v;var r=this;t.fetch({success:function(w){s.fetch({success:function(x){r.renderModalAfterFetch(w,x)},error:function(){n.error("An error occured during fetching histories:(");r.renderModalAfterFetch(w)}})},error:function(){n.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(w,t){var u=this.size_to_string(w.get("file_size"));var v=_.template(this.templateDatasetModal(),{item:w,size:u});var s=this;this.modal=new k.GalaxyModal({destructible:true,title:"Dataset Details",body:v,buttons:{Import:function(){s.importCurrentIntoHistory()},Download:function(){s.downloadCurrent()},Close:function(){s.modal.hideOrDestroy()}}});$(".peek").html(w.get("peek"));if(typeof history.models!==undefined){var r=_.template(this.templateHistorySelectInModal(),{histories:t.models});$(this.modal.elMain).find(".buttons").prepend(r);if(s.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(s.lastSelectedHistory)}}this.modal.bindEvents();this.modal.show()},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var r=[];r.push($("#id_row").attr("data-id"));var s="/api/libraries/datasets/download/uncompressed";var t={ldda_ids:r};folderContentView.processDownload(s,t);this.modal.enableButton("Import");this.modal.enableButton("Download")},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var t=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=t;var r=$("#id_row").attr("data-id");var u=new b();var s=this;u.url=u.urlRoot+t+"/contents";u.save({content:r,source:"library"},{success:function(){n.success("Dataset imported");s.modal.enableButton("Import");s.modal.enableButton("Download")},error:function(){n.error("An error occured! Dataset not imported. Please try again.");s.modal.enableButton("Import");s.modal.enableButton("Download")}})},selectAll:function(s){var r=s.target.checked;that=this;$(":checkbox").each(function(){this.checked=r;$row=$(this.parentElement.parentElement);(r)?that.makeDarkRow($row):that.makeWhiteRow($row)});this.checkTools()},selectClickedRow:function(s){var u="";var r;var t;if(s.target.localName==="input"){u=s.target;r=$(s.target.parentElement.parentElement);t="input"}else{if(s.target.localName==="td"){u=$("#"+s.target.parentElement.id).find(":checkbox")[0];r=$(s.target.parentElement);t="td"}}if(u===""){s.stopPropagation();return}if(u===undefined){s.stopPropagation();return}if(u.checked){if(t==="td"){u.checked="";this.makeWhiteRow(r)}else{if(t==="input"){this.makeDarkRow(r)}}}else{if(t==="td"){u.checked="selected";this.makeDarkRow(r)}else{if(t==="input"){this.makeWhiteRow(r)}}}this.checkTools()},makeDarkRow:function(r){r.removeClass("light");r.find("a").removeClass("light");r.addClass("dark");r.find("a").addClass("dark")},makeWhiteRow:function(r){r.removeClass("dark");r.find("a").removeClass("dark");r.addClass("light");r.find("a").addClass("light")},checkTools:function(){var r=$("#folder_table").find(":checked");if(r.length>0){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}else{$("#toolbtn_bulk_import").hide();$("#toolbtn_dl").hide()}},modalBulkImport:function(){var s=this;var r=new p();r.fetch({success:function(t){var u=_.template(s.templateBulkImportInModal(),{histories:t.models});s.modal=new k.GalaxyModal({destructible:true,title:"Import into History",body:u,buttons:{Import:function(){s.importAllIntoHistory()},Close:function(){s.modal.hideOrDestroy()}}});s.modal.bindEvents();s.modal.show()},error:function(){n.error("An error occured :(")}})},importAllIntoHistory:function(){this.modal.disableButton("Import");var t=$("select[name=dataset_import_bulk] option:selected").val();var x=$("select[name=dataset_import_bulk] option:selected").text();var z=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){z.push(this.parentElement.parentElement.id)}});var y=_.template(this.templateProgressBar(),{history_name:x});$(this.modal.elMain).find(".modal-body").html(y);var u=100/z.length;this.initProgress(u);var r=[];for(var s=z.length-1;s>=0;s--){library_dataset_id=z[s];var v=new b();var w=this;v.url=v.urlRoot+t+"/contents";v.content=library_dataset_id;v.source="library";r.push(v)}this.chainCall(r)},chainCall:function(s){var r=this;var t=s.pop();if(typeof t==="undefined"){n.success("All datasets imported");this.modal.hideOrDestroy();return}var u=$.when(t.save({content:t.content,source:t.source})).done(function(v){r.updateProgress();responses.push(v);r.chainCall(s)})},initProgress:function(r){this.progress=0;this.progressStep=r},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(r,v){var t=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){t.push(this.parentElement.parentElement.id)}});var s="/api/libraries/datasets/download/"+v;var u={ldda_ids:t};this.processDownload(s,u,"get")},processDownload:function(s,t,u){if(s&&t){t=typeof t=="string"?t:$.param(t);var r="";$.each(t.split("&"),function(){var v=this.split("=");r+='<input type="hidden" name="'+v[0]+'" value="'+v[1]+'" />'});$('<form action="'+s+'" method="'+(u||"post")+'">'+r+"</form>").appendTo("body").submit().remove();n.info("Your download will begin soon")}},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,title:"Create New Folder",body:this.templateNewFolderInModal(),buttons:{Create:function(){r.create_new_folder_event()},Close:function(){r.modal.hideOrDestroy();r.modal=null}}});this.modal.bindEvents();this.modal.show()},create_new_folder_event:function(){var r=this.serialize_new_folder();if(this.validate_new_folder(r)){var t=new c();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];t.url=t.urlRoot+"/"+current_folder_id;var s=this;t.save(r,{success:function(u){s.modal.hideOrDestroy();n.success("Folder created");s.render({id:current_folder_id})},error:function(){n.error("An error occured :(")}})}else{n.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(r){return r.name!==""}});var a=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"show_library_modal"},initialize:function(){},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; overflow: auto !important; ">');tmpl_array.push("");tmpl_array.push('<h3>New Data Libraries. This is work in progress. Report problems & ideas to <a href="mailto:marten@bx.psu.edu?Subject=DataLibraries_Feedback" target="_blank">Marten</a>.</h3>');tmpl_array.push('<a href="" id="create_new_library_btn" class="btn btn-primary file ">New Library</a>');tmpl_array.push('<table class="table table-condensed">');tmpl_array.push(" <thead>");tmpl_array.push(' <th class="button_heading"></th>');tmpl_array.push(" <th>name</th>");tmpl_array.push(" <th>description</th>");tmpl_array.push(" <th>synopsis</th> ");tmpl_array.push(" <th>model type</th> ");tmpl_array.push(" </thead>");tmpl_array.push(" <tbody>");tmpl_array.push(" <% _.each(libraries, function(library) { %>");tmpl_array.push(" <tr>");tmpl_array.push(' <td><button title="Open this library" type="button" data-id="<%- library.get("root_folder_id") %>" class="btn_open_folder btn btn-default btn-xs">');tmpl_array.push(' <span class="fa fa-folder-open"></span> browse</td>');tmpl_array.push(' <td><%- library.get("name") %></td>');tmpl_array.push(' <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("model_class")) %></td>');tmpl_array.push(" </tr>");tmpl_array.push(" <% }); %>");tmpl_array.push(" </tbody>");tmpl_array.push("</table>");tmpl_array.push("</div>");return tmpl_array.join("")},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")},render:function(){$("#center").css("overflow","auto");var r=this;libraries=new o();libraries.fetch({success:function(s){var t=_.template(r.templateLibraryList(),{libraries:s.models});r.$el.html(t)},error:function(t,s){if(s.statusCode().status===403){n.error("Please log in first. Redirecting to login page in 3s.");setTimeout(r.redirectToLogin,3000)}else{n.error("An error occured. Please try again.")}}})},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},modal:null,show_library_modal:function(s){s.preventDefault();s.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){r.create_new_library_event()},Close:function(){r.modal.hideOrDestroy()}}});this.modal.bindEvents();this.modal.show()},create_new_library_event:function(){var t=this.serialize_new_library();if(this.validate_new_library(t)){var s=new f();var r=this;s.save(t,{success:function(u){r.modal.hideOrDestroy();r.clear_library_modal();r.render();n.success("Library created")},error:function(){n.error("An error occured :(")}})}else{n.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(r){return r.name!==""}});var g=Backbone.View.extend({folderContentView:null,galaxyLibraryview:null,initialize:function(){folderContentView=new m();galaxyLibraryview=new a();library_router=new q();library_router.on("route:libraries",function(){galaxyLibraryview.render()});library_router.on("route:folder_content",function(r){folderContentView.render({id:r})});library_router.on("route:download",function(r,s){if($("#center").find(":checked").length===0){library_router.navigate("folders/"+r,{trigger:true,replace:true})}else{folderContentView.download(r,s);library_router.navigate("folders/"+r,{trigger:false,replace:true})}});Backbone.history.start();return this}});return{GalaxyApp:g}});
\ No newline at end of file
+var view=null;var library_router=null;var responses=[];define(["galaxy.modal","galaxy.masthead","utils/galaxy.utils","libs/toastr"],function(k,l,h,n){var f=Backbone.Model.extend({urlRoot:"/api/libraries"});var c=Backbone.Model.extend({urlRoot:"/api/folders"});var o=Backbone.Collection.extend({url:"/api/libraries",model:f});var i=Backbone.Model.extend({urlRoot:"/api/libraries/datasets"});var d=Backbone.Collection.extend({model:i});var e=Backbone.Model.extend({defaults:{folder:new d(),full_path:"unknown",urlRoot:"/api/folders/",id:"unknown"},parse:function(r){this.full_path=r[0].full_path;this.get("folder").reset(r[1].folder_contents);return r}});var b=Backbone.Model.extend({urlRoot:"/api/histories/"});var j=Backbone.Model.extend({url:"/api/histories/"});var p=Backbone.Collection.extend({url:"/api/histories",model:j});var q=Backbone.Router.extend({routes:{"":"libraries","folders/:id":"folder_content","folders/:folder_id/download/:format":"download"}});var m=Backbone.View.extend({el:"#center",progress:0,progressStep:1,lastSelectedHistory:"",modal:null,folders:null,initialize:function(){this.folders=[];this.queue=jQuery.Deferred();this.queue.resolve()},templateFolder:function(){var r=[];r.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; ">');r.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');r.push('<div id="library_folder_toolbar" >');r.push(' <button title="Create New Folder" id="toolbtn_create_folder" class="btn btn-primary" type="button"><span class="fa fa-plus"></span><span class="fa fa-folder-close"></span> folder</button>');r.push(' <button id="toolbtn_bulk_import" class="btn btn-primary" style="display: none; margin-left: 0.5em;" type="button"><span class="fa fa-external-link"></span> to history</button>');r.push(' <div id="toolbtn_dl" class="btn-group" style="margin-left: 0.5em; display: none; ">');r.push(' <button id="drop_toggle" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown">');r.push(' <span class="fa fa-download"></span> download <span class="caret"></span>');r.push(" </button>");r.push(' <ul class="dropdown-menu" role="menu">');r.push(' <li><a href="#/folders/<%= id %>/download/tgz">.tar.gz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/tbz">.tar.bz</a></li>');r.push(' <li><a href="#/folders/<%= id %>/download/zip">.zip</a></li>');r.push(" </ul>");r.push(" </div>");r.push("</div>");r.push('<div class="library_breadcrumb">');r.push('<a title="Return to the list of libraries" href="#">Libraries</a><b>|</b> ');r.push("<% _.each(path, function(path_item) { %>");r.push("<% if (path_item[0] != id) { %>");r.push('<a title="Return to this folder" href="#/folders/<%- path_item[0] %>"><%- path_item[1] %></a><b>|</b> ');r.push("<% } else { %>");r.push('<span title="You are in this folder"><%- path_item[1] %></span>');r.push("<% } %>");r.push("<% }); %>");r.push("</div>");r.push('<table id="folder_table" class="table table-condensed">');r.push(" <thead>");r.push(' <th style="text-align: center; width: 20px; "><input id="select-all-checkboxes" style="margin: 0;" type="checkbox"></th>');r.push(' <th class="button_heading">view</th>');r.push(" <th>name</th>");r.push(" <th>data type</th>");r.push(" <th>size</th>");r.push(" <th>date (UTC)</th>");r.push(" </thead>");r.push(" <tbody>");r.push(" <td></td>");r.push(' <td><button title="Go to parent folder" type="button" data-id="<%- upper_folder_id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-arrow-up"></span> .. go up</td>');r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" <td></td>");r.push(" </tr>");r.push(" <% _.each(items, function(content_item) { %>");r.push(' <tr class="folder_row light" id="<%- content_item.id %>">');r.push(' <% if (content_item.get("type") === "folder") { %>');r.push(" <td></td>");r.push(' <td><button title="Open this folder" type="button" data-id="<%- content_item.id %>" class="btn_open_folder btn btn-default btn-xs">');r.push(' <span class="fa fa-folder-open"></span> browse</td>');r.push(' <td><%- content_item.get("name") %>');r.push(' <% if (content_item.get("item_count") === 0) { %>');r.push(' <span class="muted">(empty folder)</span>');r.push(" <% } %>");r.push(" </td>");r.push(" <td>folder</td>");r.push(' <td><%= _.escape(content_item.get("item_count")) %> item(s)</td>');r.push(" <% } else { %>");r.push(' <td style="text-align: center; "><input style="margin: 0;" type="checkbox"></td>');r.push(" <td>");r.push(' <button title="See details of this dataset" type="button" class="library-dataset btn btn-default btn-xs">');r.push(' <span class="fa fa-eye"></span> details');r.push(" </button>");r.push(" </td>");r.push(' <td><%- content_item.get("name") %></td>');r.push(' <td><%= _.escape(content_item.get("data_type")) %></td>');r.push(' <td><%= _.escape(content_item.get("readable_size")) %></td>');r.push(" <% } %> ");r.push(' <td><%= _.escape(content_item.get("time_updated")) %></td>');r.push(" </tr>");r.push(" <% }); %>");r.push(" ");r.push(" </tbody>");r.push("</table>");r.push("</div>");return r.join("")},templateDatasetModal:function(){var r=[];r.push('<div id="dataset_info_modal">');r.push(' <table class="table table-striped table-condensed">');r.push(" <tr>");r.push(' <th scope="row" id="id_row" data-id="<%= _.escape(item.get("ldda_id")) %>">Name</th>');r.push(' <td><%= _.escape(item.get("name")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Data type</th>');r.push(' <td><%= _.escape(item.get("data_type")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Genome build</th>');r.push(' <td><%= _.escape(item.get("genome_build")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Size</th>');r.push(" <td><%= _.escape(size) %></td>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Date uploaded (UTC)</th>');r.push(' <td><%= _.escape(item.get("date_uploaded")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Uploaded by</th>');r.push(' <td><%= _.escape(item.get("uploaded_by")) %></td>');r.push(" </tr>");r.push(' <tr scope="row">');r.push(' <th scope="row">Data Lines</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_data_lines")) %></td>');r.push(" </tr>");r.push(' <th scope="row">Comment Lines</th>');r.push(' <% if (item.get("metadata_comment_lines") === "") { %>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_comment_lines")) %></td>');r.push(" <% } else { %>");r.push(' <td scope="row">unknown</td>');r.push(" <% } %>");r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Number of Columns</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_columns")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Column Types</th>');r.push(' <td scope="row"><%= _.escape(item.get("metadata_column_types")) %></td>');r.push(" </tr>");r.push(" <tr>");r.push(' <th scope="row">Miscellaneous information</th>');r.push(' <td scope="row"><%= _.escape(item.get("misc_blurb")) %></td>');r.push(" </tr>");r.push(" </table>");r.push(' <pre class="peek">');r.push(" </pre>");r.push("</div>");return r.join("")},templateHistorySelectInModal:function(){var r=[];r.push('<span id="history_modal_combo" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_single" name="dataset_import_single" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateBulkImportInModal:function(){var r=[];r.push('<span id="history_modal_combo_bulk" style="width:90%; margin-left: 1em; margin-right: 1em; ">');r.push("Select history: ");r.push('<select id="dataset_import_bulk" name="dataset_import_bulk" style="width:50%; margin-bottom: 1em; "> ');r.push(" <% _.each(histories, function(history) { %>");r.push(' <option value="<%= _.escape(history.get("id")) %>"><%= _.escape(history.get("name")) %></option>');r.push(" <% }); %>");r.push("</select>");r.push("</span>");return r.join("")},templateProgressBar:function(){var r=[];r.push('<div class="import_text">');r.push("Importing selected datasets to history <b><%= _.escape(history_name) %></b>");r.push("</div>");r.push('<div class="progress">');r.push(' <div class="progress-bar progress-bar-import" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 00%;">');r.push(' <span class="completion_span">0% Complete</span>');r.push(" </div>");r.push("</div>");r.push("");return r.join("")},templateNewFolderInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_folder_modal">');tmpl_array.push("<form>");tmpl_array.push('<input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push('<input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push("</form>");tmpl_array.push("</div>");return tmpl_array.join("")},events:{"click #select-all-checkboxes":"selectAll","click .folder_row":"selectClickedRow","click #toolbtn_bulk_import":"modalBulkImport","click #toolbtn_dl":"bulkDownload","click .library-dataset":"showDatasetDetails","click #toolbtn_create_folder":"createFolderFromModal","click .btn_open_folder":"navigateToFolder"},render:function(r){$("#center").css("overflow","auto");view=this;var t=this;var s=new e({id:r.id});s.url=s.attributes.urlRoot+r.id+"/contents";s.fetch({success:function(u){for(var w=0;w<s.attributes.folder.models.length;w++){var v=s.attributes.folder.models[w];if(v.get("type")==="file"){v.set("readable_size",t.size_to_string(v.get("file_size")))}}var y=s.full_path;var z;if(y.length===1){z=0}else{z=y[y.length-2][0]}var x=_.template(t.templateFolder(),{path:s.full_path,items:s.attributes.folder.models,id:r.id,upper_folder_id:z});t.$el.html(x)},error:function(){n.error("An error occured :(")}})},size_to_string:function(r){var s="";if(r>=100000000000){r=r/100000000000;s="TB"}else{if(r>=100000000){r=r/100000000;s="GB"}else{if(r>=100000){r=r/100000;s="MB"}else{if(r>=100){r=r/100;s="KB"}else{r=r*10;s="b"}}}}return(Math.round(r)/10)+s},navigateToFolder:function(s){var r=$(s.target).attr("data-id");if(typeof r==="undefined"){return false}else{if(r==="0"){library_router.navigate("#",{trigger:true,replace:true})}else{library_router.navigate("folders/"+r,{trigger:true,replace:true})}}},showDatasetDetails:function(u){u.preventDefault();var v=$(u.target).parent().parent().attr("id");var t=new i();var s=new p();t.id=v;var r=this;t.fetch({success:function(w){s.fetch({success:function(x){r.renderModalAfterFetch(w,x)},error:function(){n.error("An error occured during fetching histories:(");r.renderModalAfterFetch(w)}})},error:function(){n.error("An error occured during loading dataset details :(")}})},renderModalAfterFetch:function(w,t){var u=this.size_to_string(w.get("file_size"));var v=_.template(this.templateDatasetModal(),{item:w,size:u});var s=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Dataset Details",body:v,buttons:{Import:function(){s.importCurrentIntoHistory()},Download:function(){s.downloadCurrent()},Close:function(){s.modal.hideOrDestroy()}}});$(".peek").html(w.get("peek"));if(typeof history.models!==undefined){var r=_.template(this.templateHistorySelectInModal(),{histories:t.models});$(this.modal.elMain).find(".buttons").prepend(r);if(s.lastSelectedHistory.length>0){$(this.modal.elMain).find("#dataset_import_single").val(s.lastSelectedHistory)}}this.modal.show()},downloadCurrent:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var r=[];r.push($("#id_row").attr("data-id"));var s="/api/libraries/datasets/download/uncompressed";var t={ldda_ids:r};folderContentView.processDownload(s,t);this.modal.enableButton("Import");this.modal.enableButton("Download")},importCurrentIntoHistory:function(){this.modal.disableButton("Import");this.modal.disableButton("Download");var t=$(this.modal.elMain).find("select[name=dataset_import_single] option:selected").val();this.lastSelectedHistory=t;var r=$("#id_row").attr("data-id");var u=new b();var s=this;u.url=u.urlRoot+t+"/contents";u.save({content:r,source:"library"},{success:function(){n.success("Dataset imported");s.modal.enableButton("Import");s.modal.enableButton("Download")},error:function(){n.error("An error occured! Dataset not imported. Please try again.");s.modal.enableButton("Import");s.modal.enableButton("Download")}})},selectAll:function(s){var r=s.target.checked;that=this;$(":checkbox").each(function(){this.checked=r;$row=$(this.parentElement.parentElement);(r)?that.makeDarkRow($row):that.makeWhiteRow($row)});this.checkTools()},selectClickedRow:function(s){var u="";var r;var t;if(s.target.localName==="input"){u=s.target;r=$(s.target.parentElement.parentElement);t="input"}else{if(s.target.localName==="td"){u=$("#"+s.target.parentElement.id).find(":checkbox")[0];r=$(s.target.parentElement);t="td"}}if(u===""){s.stopPropagation();return}if(u===undefined){s.stopPropagation();return}if(u.checked){if(t==="td"){u.checked="";this.makeWhiteRow(r)}else{if(t==="input"){this.makeDarkRow(r)}}}else{if(t==="td"){u.checked="selected";this.makeDarkRow(r)}else{if(t==="input"){this.makeWhiteRow(r)}}}this.checkTools()},makeDarkRow:function(r){r.removeClass("light");r.find("a").removeClass("light");r.addClass("dark");r.find("a").addClass("dark")},makeWhiteRow:function(r){r.removeClass("dark");r.find("a").removeClass("dark");r.addClass("light");r.find("a").addClass("light")},checkTools:function(){var r=$("#folder_table").find(":checked");if(r.length>0){$("#toolbtn_bulk_import").show();$("#toolbtn_dl").show()}else{$("#toolbtn_bulk_import").hide();$("#toolbtn_dl").hide()}},modalBulkImport:function(){var s=this;var r=new p();r.fetch({success:function(t){var u=_.template(s.templateBulkImportInModal(),{histories:t.models});s.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Import into History",body:u,buttons:{Import:function(){s.importAllIntoHistory()},Close:function(){s.modal.hideOrDestroy()}}});s.modal.show()},error:function(){n.error("An error occured :(")}})},importAllIntoHistory:function(){this.modal.disableButton("Import");var t=$("select[name=dataset_import_bulk] option:selected").val();var x=$("select[name=dataset_import_bulk] option:selected").text();var z=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){z.push(this.parentElement.parentElement.id)}});var y=_.template(this.templateProgressBar(),{history_name:x});$(this.modal.elMain).find(".modal-body").html(y);var u=100/z.length;this.initProgress(u);var r=[];for(var s=z.length-1;s>=0;s--){library_dataset_id=z[s];var v=new b();var w=this;v.url=v.urlRoot+t+"/contents";v.content=library_dataset_id;v.source="library";r.push(v)}this.chainCall(r)},chainCall:function(s){var r=this;var t=s.pop();if(typeof t==="undefined"){n.success("All datasets imported");this.modal.hideOrDestroy();return}var u=$.when(t.save({content:t.content,source:t.source})).done(function(v){r.updateProgress();responses.push(v);r.chainCall(s)})},initProgress:function(r){this.progress=0;this.progressStep=r},updateProgress:function(){this.progress+=this.progressStep;$(".progress-bar-import").width(Math.round(this.progress)+"%");txt_representation=Math.round(this.progress)+"% Complete";$(".completion_span").text(txt_representation)},download:function(r,v){var t=[];$("#folder_table").find(":checked").each(function(){if(this.parentElement.parentElement.id!=""){t.push(this.parentElement.parentElement.id)}});var s="/api/libraries/datasets/download/"+v;var u={ldda_ids:t};this.processDownload(s,u,"get")},processDownload:function(s,t,u){if(s&&t){t=typeof t=="string"?t:$.param(t);var r="";$.each(t.split("&"),function(){var v=this.split("=");r+='<input type="hidden" name="'+v[0]+'" value="'+v[1]+'" />'});$('<form action="'+s+'" method="'+(u||"post")+'">'+r+"</form>").appendTo("body").submit().remove();n.info("Your download will begin soon")}},createFolderFromModal:function(){event.preventDefault();event.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Create New Folder",body:this.templateNewFolderInModal(),buttons:{Create:function(){r.create_new_folder_event()},Close:function(){r.modal.hideOrDestroy();r.modal=null}}});this.modal.show()},create_new_folder_event:function(){var r=this.serialize_new_folder();if(this.validate_new_folder(r)){var t=new c();url_items=Backbone.history.fragment.split("/");current_folder_id=url_items[url_items.length-1];t.url=t.urlRoot+"/"+current_folder_id;var s=this;t.save(r,{success:function(u){s.modal.hideOrDestroy();n.success("Folder created");s.render({id:current_folder_id})},error:function(){n.error("An error occured :(")}})}else{n.error("Folder's name is missing")}return false},serialize_new_folder:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val()}},validate_new_folder:function(r){return r.name!==""}});var a=Backbone.View.extend({el:"#center",events:{"click #create_new_library_btn":"show_library_modal"},initialize:function(){},templateLibraryList:function(){tmpl_array=[];tmpl_array.push('<div id="library_container" style="width: 90%; margin: auto; margin-top: 2em; overflow: auto !important; ">');tmpl_array.push("");tmpl_array.push('<h3>Data Libraries Beta Test. This is work in progress. Please report problems & ideas via <a href="mailto:galaxy-bugs@bx.psu.edu?Subject=DataLibrariesBeta_Feedback" target="_blank">email</a> and <a href="https://trello.com/c/nwYQNFPK/56-data-library-ui-progressive-display-of-fol…" target="_blank">Trello</a>.</h3>');tmpl_array.push('<a href="" id="create_new_library_btn" class="btn btn-primary file ">New Library</a>');tmpl_array.push('<table class="table table-condensed">');tmpl_array.push(" <thead>");tmpl_array.push(' <th class="button_heading"></th>');tmpl_array.push(" <th>name</th>");tmpl_array.push(" <th>description</th>");tmpl_array.push(" <th>synopsis</th> ");tmpl_array.push(" <th>model type</th> ");tmpl_array.push(" </thead>");tmpl_array.push(" <tbody>");tmpl_array.push(" <% _.each(libraries, function(library) { %>");tmpl_array.push(" <tr>");tmpl_array.push(' <td><button title="Open this library" type="button" data-id="<%- library.get("root_folder_id") %>" class="btn_open_folder btn btn-default btn-xs">');tmpl_array.push(' <span class="fa fa-folder-open"></span> browse</td>');tmpl_array.push(' <td><%- library.get("name") %></td>');tmpl_array.push(' <td><%= _.escape(library.get("description")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("synopsis")) %></td>');tmpl_array.push(' <td><%= _.escape(library.get("model_class")) %></td>');tmpl_array.push(" </tr>");tmpl_array.push(" <% }); %>");tmpl_array.push(" </tbody>");tmpl_array.push("</table>");tmpl_array.push("</div>");return tmpl_array.join("")},templateNewLibraryInModal:function(){tmpl_array=[];tmpl_array.push('<div id="new_library_modal">');tmpl_array.push(" <form>");tmpl_array.push(' <input type="text" name="Name" value="" placeholder="Name">');tmpl_array.push(' <input type="text" name="Description" value="" placeholder="Description">');tmpl_array.push(' <input type="text" name="Synopsis" value="" placeholder="Synopsis">');tmpl_array.push(" </form>");tmpl_array.push("</div>");return tmpl_array.join("")},render:function(){$("#center").css("overflow","auto");var r=this;libraries=new o();libraries.fetch({success:function(s){var t=_.template(r.templateLibraryList(),{libraries:s.models});r.$el.html(t)},error:function(t,s){if(s.statusCode().status===403){n.info("Please log in first. Redirecting to login page in 3s.");setTimeout(r.redirectToLogin,3000)}else{n.error("An error occured. Please try again.")}}})},redirectToHome:function(){window.location="../"},redirectToLogin:function(){window.location="/user/login"},modal:null,show_library_modal:function(s){s.preventDefault();s.stopPropagation();var r=this;this.modal=new k.GalaxyModal({destructible:true,bindClosingEvents:true,title:"Create New Library",body:this.templateNewLibraryInModal(),buttons:{Create:function(){r.create_new_library_event()},Close:function(){r.modal.hideOrDestroy()}}});this.modal.show()},create_new_library_event:function(){var t=this.serialize_new_library();if(this.validate_new_library(t)){var s=new f();var r=this;s.save(t,{success:function(u){r.modal.hideOrDestroy();r.clear_library_modal();r.render();n.success("Library created")},error:function(){n.error("An error occured :(")}})}else{n.error("Library's name is missing")}return false},clear_library_modal:function(){$("input[name='Name']").val("");$("input[name='Description']").val("");$("input[name='Synopsis']").val("")},serialize_new_library:function(){return{name:$("input[name='Name']").val(),description:$("input[name='Description']").val(),synopsis:$("input[name='Synopsis']").val()}},validate_new_library:function(r){return r.name!==""}});var g=Backbone.View.extend({folderContentView:null,galaxyLibraryview:null,initialize:function(){folderContentView=new m();galaxyLibraryview=new a();library_router=new q();library_router.on("route:libraries",function(){galaxyLibraryview.render()});library_router.on("route:folder_content",function(r){folderContentView.render({id:r})});library_router.on("route:download",function(r,s){if($("#center").find(":checked").length===0){library_router.navigate("folders/"+r,{trigger:true,replace:true})}else{folderContentView.download(r,s);library_router.navigate("folders/"+r,{trigger:false,replace:true})}});Backbone.history.start();return this}});return{GalaxyApp:g}});
\ No newline at end of file
diff -r 9fe1a6fc375b3fad14dac271ed8f85e02fc6ef6d -r c28f10187bb86e0f18d36c1a7086af8615c87c97 static/scripts/packed/galaxy.modal.js
--- a/static/scripts/packed/galaxy.modal.js
+++ b/static/scripts/packed/galaxy.modal.js
@@ -1,1 +1,1 @@
-define([],function(){var a=Backbone.View.extend({elMain:"#everything",optionsDefault:{title:"galaxy-modal",body:"",backdrop:true,height:null,width:null},options:{destructible:false},initialize:function(b){self=this;if(b){this.create(b)}},hideOrDestroy:function(){if(this.options.destructible){self.destroy()}else{self.hide()}},bindEvents:function(){$(document).on("keyup",function(b){if(b.keyCode==27){self.hideOrDestroy()}});$("html").on("click",function(b){self.hideOrDestroy()});$(".modal-content").on("click",function(b){b.stopPropagation()})},unbindEvents:function(){$(document).off("keyup",function(b){if(b.keyCode==27){self.hideOrDestroy()}});$("html").off("click",function(b){self.hideOrDestroy()});$(".modal-content").off("click",function(b){b.stopPropagation()})},show:function(b){this.initialize(b);if(this.options.height){this.$body.css("height",this.options.height);this.$body.css("overflow","hidden")}else{this.$body.css("max-height",$(window).height()/2)}if(this.options.width){this.$dialog.css("width",this.options.width)}if(this.visible){this.$el.show()}else{this.$el.fadeIn("fast")}this.visible=true},hide:function(){this.$el.fadeOut("fast");this.visible=false;this.unbindEvents()},destroy:function(){this.visible=false;this.unbindEvents();this.$el.remove()},create:function(c){this.options=_.defaults(c,this.optionsDefault);if(this.options.body=="progress"){this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')}if(this.$el){this.$el.remove()}this.setElement(this.template(this.options.title));this.$dialog=(this.$el).find(".modal-dialog");this.$body=(this.$el).find(".modal-body");this.$footer=(this.$el).find(".modal-footer");this.$buttons=(this.$el).find(".buttons");this.$backdrop=(this.$el).find(".modal-backdrop");this.$body.html(this.options.body);if(!this.options.backdrop){this.$backdrop.removeClass("in")}if(this.options.buttons){var b=this;$.each(this.options.buttons,function(d,e){b.$buttons.append($('<button id="'+String(d).toLowerCase()+'"></button>').text(d).click(e)).append(" ")})}else{this.$footer.hide()}$(this.elMain).append($(this.el))},enableButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).prop("disabled",false)},disableButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).prop("disabled",true)},hideButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).hide()},showButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).show()},scrollTop:function(){return this.$body.scrollTop()},template:function(b){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+b+'</h4></div><div class="modal-body"></div><div class="modal-footer"><div class="buttons" style="float: right;"></div></div></div</div></div>'}});return{GalaxyModal:a}});
\ No newline at end of file
+define([],function(){var a=Backbone.View.extend({elMain:"#everything",optionsDefault:{title:"galaxy-modal",body:"",backdrop:true,height:null,width:null},eventsBound:false,options:{destructible:false,bindClosingEvents:false},initialize:function(b){self=this;if(b){this.create(b)}},hideOrDestroy:function(){self.visible=false;self.unbindEvents();if(self.options.destructible){self.$el.remove()}else{self.hide()}},hide:function(){this.visible=false;this.$el.fadeOut("fast")},bindEvents:function(){$(document).on("keyup",function(b){if(b.keyCode==27){self.hideOrDestroy()}});$("html").on("click",self.hideOrDestroy);$(".modal-content").on("click",function(b){b.stopPropagation()});self.eventsBound=true},unbindEvents:function(){$(document).off("keyup",function(b){if(b.keyCode==27){self.hideOrDestroy()}});$("html").off("click",function(b){self.hideOrDestroy()});$(".modal-content").off("click",function(b){b.stopPropagation()});self.eventsBound=false},show:function(b){this.initialize(b);if(this.options.height){this.$body.css("height",this.options.height);this.$body.css("overflow","hidden")}else{this.$body.css("max-height",$(window).height()/2)}if(this.options.width){this.$dialog.css("width",this.options.width)}if(this.visible){this.$el.show()}else{this.$el.fadeIn("fast")}this.visible=true},create:function(c){this.options=_.defaults(c,this.optionsDefault);if(this.options.body=="progress"){this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')}if(this.$el){this.$el.remove()}this.setElement(this.template(this.options.title));this.$dialog=(this.$el).find(".modal-dialog");this.$body=(this.$el).find(".modal-body");this.$footer=(this.$el).find(".modal-footer");this.$buttons=(this.$el).find(".buttons");this.$backdrop=(this.$el).find(".modal-backdrop");this.$body.html(this.options.body);if(!this.options.backdrop){this.$backdrop.removeClass("in")}if(this.options.buttons){var b=this;$.each(this.options.buttons,function(d,e){b.$buttons.append($('<button id="'+String(d).toLowerCase()+'"></button>').text(d).click(e)).append(" ")})}else{this.$footer.hide()}$(this.elMain).append($(this.el));if(this.options.bindClosingEvents&&!this.eventsBound){this.bindEvents()}},enableButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).prop("disabled",false)},disableButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).prop("disabled",true)},hideButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).hide()},showButton:function(b){this.$buttons.find("#"+String(b).toLowerCase()).show()},scrollTop:function(){return this.$body.scrollTop()},template:function(b){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+b+'</h4></div><div class="modal-body"></div><div class="modal-footer"><div class="buttons" style="float: right;"></div></div></div</div></div>'}});return{GalaxyModal:a}});
\ No newline at end of file
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
1
0