Merge branch '41214-26' of git://github.com/samhemelryk/moodle
authorDan Poltawski <dan@moodle.com>
Mon, 2 Sep 2013 09:32:08 +0000 (17:32 +0800)
committerDan Poltawski <dan@moodle.com>
Mon, 2 Sep 2013 09:32:08 +0000 (17:32 +0800)
Conflicts:
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-min.js

77 files changed:
admin/tool/generator/classes/backend.php
admin/tool/generator/classes/course_backend.php [new file with mode: 0644]
admin/tool/generator/classes/make_form.php
admin/tool/generator/classes/site_backend.php [new file with mode: 0644]
admin/tool/generator/cli/maketestcourse.php
admin/tool/generator/cli/maketestsite.php [new file with mode: 0644]
admin/tool/generator/lang/en/tool_generator.php
admin/tool/generator/maketestcourse.php
admin/tool/generator/tests/maketestcourse_test.php
admin/tool/generator/version.php
admin/tool/uploaduser/index.php
admin/user.php
auth/db/auth.php
auth/email/auth.php
auth/ldap/auth.php
auth/mnet/auth.php
badges/classes/observer.php
badges/external.php
badges/mybackpack.php
badges/renderer.php
badges/tests/badgeslib_test.php
enrol/ldap/lang/en/enrol_ldap.php
enrol/ldap/lib.php
enrol/manual/locallib.php
enrol/meta/classes/observer.php [new file with mode: 0644]
enrol/meta/db/events.php
enrol/meta/locallib.php
enrol/meta/tests/plugin_test.php
enrol/tests/enrollib_test.php
files/renderer.php
grade/export/lib.php
lang/en/badges.php
lang/en/cache.php
lang/en/enrol.php
lang/en/moodle.php
lib/badgeslib.php
lib/behat/classes/util.php
lib/blocklib.php
lib/classes/event/user_created.php [new file with mode: 0644]
lib/classes/event/user_deleted.php [new file with mode: 0644]
lib/classes/event/user_enrolment_created.php [new file with mode: 0644]
lib/classes/event/user_enrolment_deleted.php [new file with mode: 0644]
lib/classes/event/user_enrolment_updated.php [new file with mode: 0644]
lib/classes/event/user_loggedout.php [new file with mode: 0644]
lib/classes/event/user_updated.php [new file with mode: 0644]
lib/configonlylib.php
lib/db/caches.php
lib/db/events.php
lib/dml/mssql_native_moodle_database.php
lib/dml/sqlsrv_native_moodle_database.php
lib/editor/tinymce/module.js
lib/enrollib.php
lib/moodlelib.php
lib/outputcomponents.php
lib/outputrenderers.php
lib/tests/configonlylib_test.php
lib/tests/moodlelib_test.php
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-debug.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-min.js
lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue.js
lib/yui/src/notification/js/dialogue.js
mod/assign/locallib.php
mod/data/view.php
mod/forum/classes/observer.php [new file with mode: 0644]
mod/forum/db/events.php
mod/forum/lib.php
mod/forum/tests/lib_test.php
repository/filepicker.js
theme/base/style/core.css
theme/bootstrapbase/less/moodle/core.less
theme/bootstrapbase/style/moodle.css
user/edit.php
user/editadvanced.php
user/emailupdate.php
user/lib.php
user/tests/userlib_test.php [new file with mode: 0644]
version.php

index beed421..20b3370 100644 (file)
 // You should have received a copy of the GNU General Public License
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
+/**
+ * Backend generic code.
+ *
+ * @package tool_generator
+ * @copyright 2013 The Open University
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
 defined('MOODLE_INTERNAL') || die();
 
 /**
- * Backend code for the 'make large course' tool.
+ * Backend generic code for all tool_generator commands.
  *
+ * @abstract
  * @package tool_generator
  * @copyright 2013 The Open University
  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-class tool_generator_backend {
+abstract class tool_generator_backend {
     /**
      * @var int Lowest (smallest) size index
      */
@@ -38,126 +47,56 @@ class tool_generator_backend {
     const DEFAULT_SIZE = 3;
 
     /**
-     * @var array Number of sections in course
-     */
-    private static $paramsections = array(1, 10, 100, 500, 1000, 2000);
-    /**
-     * @var array Number of Page activities in course
-     */
-    private static $parampages = array(1, 50, 200, 1000, 5000, 10000);
-    /**
-     * @var array Number of students enrolled in course
-     */
-    private static $paramusers = array(1, 100, 1000, 10000, 50000, 100000);
-    /**
-     * Total size of small files: 1KB, 1MB, 10MB, 100MB, 1GB, 2GB.
-     *
-     * @var array Number of small files created in a single file activity
-     */
-    private static $paramsmallfilecount = array(1, 64, 128, 1024, 16384, 32768);
-    /**
-     * @var array Size of small files (to make the totals into nice numbers)
-     */
-    private static $paramsmallfilesize = array(1024, 16384, 81920, 102400, 65536, 65536);
-    /**
-     * Total size of big files: 8KB, 8MB, 80MB, 800MB, 8GB, 16GB.
-     *
-     * @var array Number of big files created as individual file activities
-     */
-    private static $parambigfilecount = array(1, 2, 5, 10, 10, 10);
-    /**
-     * @var array Size of each large file
-     */
-    private static $parambigfilesize = array(8192, 4194304, 16777216, 83886080,
-            858993459, 1717986918);
-    /**
-     * @var array Number of forum discussions
-     */
-    private static $paramforumdiscussions = array(1, 10, 100, 500, 1000, 2000);
-    /**
-     * @var array Number of forum posts per discussion
-     */
-    private static $paramforumposts = array(2, 2, 5, 10, 10, 10);
-
-    /**
-     * @var string Course shortname
-     */
-    private $shortname;
-
-    /**
-     * @var int Size code (index in the above arrays)
+     * @var bool True if we want a fixed dataset or false to generate random data
      */
-    private $size;
+    protected $fixeddataset;
 
     /**
      * @var bool True if displaying progress
      */
-    private $progress;
-
-    /**
-     * @var testing_data_generator Data generator
-     */
-    private $generator;
-
-    /**
-     * @var stdClass Course object
-     */
-    private $course;
+    protected $progress;
 
     /**
      * @var int Epoch time at which last dot was displayed
      */
-    private $lastdot;
+    protected $lastdot;
 
     /**
      * @var int Epoch time at which last percentage was displayed
      */
-    private $lastpercentage;
+    protected $lastpercentage;
 
     /**
      * @var int Epoch time at which current step (current set of dots) started
      */
-    private $starttime;
+    protected $starttime;
 
     /**
-     * @var array Array from test user number (1...N) to userid in database
+     * @var int Size code (index in the above arrays)
      */
-    private $userids;
+    protected $size;
 
     /**
-     * Constructs object ready to create course.
+     * Generic generator class
      *
-     * @param string $shortname Course shortname
      * @param int $size Size as numeric index
+     * @param bool $fixeddataset To use fixed or random data
      * @param bool $progress True if progress information should be displayed
-     * @return int Course id
      * @throws coding_exception If parameters are invalid
      */
-    public function __construct($shortname, $size, $progress = true) {
+    public function __construct($size, $fixeddataset = false, $progress = true) {
+
         // Check parameter.
         if ($size < self::MIN_SIZE || $size > self::MAX_SIZE) {
             throw new coding_exception('Invalid size');
         }
 
         // Set parameters.
-        $this->shortname = $shortname;
         $this->size = $size;
+        $this->fixeddataset = $fixeddataset;
         $this->progress = $progress;
     }
 
-    /**
-     * Gets a list of size choices supported by this backend.
-     *
-     * @return array List of size (int) => text description for display
-     */
-    public static function get_size_choices() {
-        $options = array();
-        for ($size = self::MIN_SIZE; $size <= self::MAX_SIZE; $size++) {
-            $options[$size] = get_string('size_' . $size, 'tool_generator');
-        }
-        return $options;
-    }
-
     /**
      * Converts a size name into the numeric constant.
      *
@@ -174,367 +113,13 @@ class tool_generator_backend {
         throw new coding_exception("Unknown size name '$sizename'");
     }
 
-    /**
-     * Checks that a shortname is available (unused).
-     *
-     * @param string $shortname Proposed course shortname
-     * @return string An error message if the name is unavailable or '' if OK
-     */
-    public static function check_shortname_available($shortname) {
-        global $DB;
-        $fullname = $DB->get_field('course', 'fullname',
-                array('shortname' => $shortname), IGNORE_MISSING);
-        if ($fullname !== false) {
-            // I wanted to throw an exception here but it is not possible to
-            // use strings from moodle.php in exceptions, and I didn't want
-            // to duplicate the string in tool_generator, so I changed this to
-            // not use exceptions.
-            return get_string('shortnametaken', 'moodle', $fullname);
-        }
-        return '';
-    }
-
-    /**
-     * Runs the entire 'make' process.
-     *
-     * @return int Course id
-     */
-    public function make() {
-        global $DB, $CFG;
-        require_once($CFG->dirroot . '/lib/phpunit/classes/util.php');
-
-        raise_memory_limit(MEMORY_EXTRA);
-
-        if ($this->progress && !CLI_SCRIPT) {
-            echo html_writer::start_tag('ul');
-        }
-
-        $entirestart = microtime(true);
-
-        // Start transaction.
-        $transaction = $DB->start_delegated_transaction();
-
-        // Get generator.
-        $this->generator = phpunit_util::get_data_generator();
-
-        // Make course.
-        $this->course = $this->create_course();
-        $this->create_users();
-        $this->create_pages();
-        $this->create_small_files();
-        $this->create_big_files();
-        $this->create_forum();
-
-        // Log total time.
-        $this->log('complete', round(microtime(true) - $entirestart, 1));
-
-        if ($this->progress && !CLI_SCRIPT) {
-            echo html_writer::end_tag('ul');
-        }
-
-        // Commit transaction and finish.
-        $transaction->allow_commit();
-        return $this->course->id;
-    }
-
-    /**
-     * Creates the actual course.
-     *
-     * @return stdClass Course record
-     */
-    private function create_course() {
-        $this->log('createcourse', $this->shortname);
-        $courserecord = array('shortname' => $this->shortname,
-                'fullname' => get_string('fullname', 'tool_generator',
-                    array('size' => get_string('shortsize_' . $this->size, 'tool_generator'))),
-                'numsections' => self::$paramsections[$this->size]);
-        return $this->generator->create_course($courserecord, array('createsections' => true));
-    }
-
-    /**
-     * Creates a number of user accounts and enrols them on the course.
-     * Note: Existing user accounts that were created by this system are
-     * reused if available.
-     */
-    private function create_users() {
-        global $DB;
-
-        // Work out total number of users.
-        $count = self::$paramusers[$this->size];
-
-        // Get existing users in order. We will 'fill up holes' in this up to
-        // the required number.
-        $this->log('checkaccounts', $count);
-        $nextnumber = 1;
-        $rs = $DB->get_recordset_select('user', $DB->sql_like('username', '?'),
-                array('tool_generator_%'), 'username', 'id, username');
-        foreach ($rs as $rec) {
-            // Extract number from username.
-            $matches = array();
-            if (!preg_match('~^tool_generator_([0-9]{6})$~', $rec->username, $matches)) {
-                continue;
-            }
-            $number = (int)$matches[1];
-
-            // Create missing users in range up to this.
-            if ($number != $nextnumber) {
-                $this->create_user_accounts($nextnumber, min($number - 1, $count));
-            } else {
-                $this->userids[$number] = (int)$rec->id;
-            }
-
-            // Stop if we've got enough users.
-            $nextnumber = $number + 1;
-            if ($number >= $count) {
-                break;
-            }
-        }
-        $rs->close();
-
-        // Create users from end of existing range.
-        if ($nextnumber <= $count) {
-            $this->create_user_accounts($nextnumber, $count);
-        }
-
-        // Assign all users to course.
-        $this->log('enrol', $count, true);
-
-        $enrolplugin = enrol_get_plugin('manual');
-        $instances = enrol_get_instances($this->course->id, true);
-        foreach ($instances as $instance) {
-            if ($instance->enrol === 'manual') {
-                break;
-            }
-        }
-        if ($instance->enrol !== 'manual') {
-            throw new coding_exception('No manual enrol plugin in course');
-        }
-        $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
-
-        for ($number = 1; $number <= $count; $number++) {
-            // Enrol user.
-            $enrolplugin->enrol_user($instance, $this->userids[$number], $role->id);
-            $this->dot($number, $count);
-        }
-
-        $this->end_log();
-    }
-
-    /**
-     * Creates user accounts with a numeric range.
-     *
-     * @param int $first Number of first user
-     * @param int $last Number of last user
-     */
-    private function create_user_accounts($first, $last) {
-        $this->log('createaccounts', (object)array('from' => $first, 'to' => $last), true);
-        $count = $last - $first + 1;
-        $done = 0;
-        for ($number = $first; $number <= $last; $number++, $done++) {
-            // Work out username with 6-digit number.
-            $textnumber = (string)$number;
-            while (strlen($textnumber) < 6) {
-                $textnumber = '0' . $textnumber;
-            }
-            $username = 'tool_generator_' . $textnumber;
-
-            // Create user account.
-            $record = array('firstname' => get_string('firstname', 'tool_generator'),
-                    'lastname' => $number, 'username' => $username);
-            $user = $this->generator->create_user($record);
-            $this->userids[$number] = (int)$user->id;
-            $this->dot($done, $count);
-        }
-        $this->end_log();
-    }
-
-    /**
-     * Creates a number of Page activities.
-     */
-    private function create_pages() {
-        // Set up generator.
-        $pagegenerator = $this->generator->get_plugin_generator('mod_page');
-
-        // Create pages.
-        $number = self::$parampages[$this->size];
-        $this->log('createpages', $number, true);
-        for ($i=0; $i<$number; $i++) {
-            $record = array('course' => $this->course->id);
-            $options = array('section' => $this->get_random_section());
-            $pagegenerator->create_instance($record, $options);
-            $this->dot($i, $number);
-        }
-
-        $this->end_log();
-    }
-
-    /**
-     * Creates one resource activity with a lot of small files.
-     */
-    private function create_small_files() {
-        $count = self::$paramsmallfilecount[$this->size];
-        $this->log('createsmallfiles', $count, true);
-
-        // Create resource with default textfile only.
-        $resourcegenerator = $this->generator->get_plugin_generator('mod_resource');
-        $record = array('course' => $this->course->id,
-                'name' => get_string('smallfiles', 'tool_generator'));
-        $options = array('section' => 0);
-        $resource = $resourcegenerator->create_instance($record, $options);
-
-        // Add files.
-        $fs = get_file_storage();
-        $context = context_module::instance($resource->cmid);
-        $filerecord = array('component' => 'mod_resource', 'filearea' => 'content',
-                'contextid' => $context->id, 'itemid' => 0, 'filepath' => '/');
-        for ($i = 0; $i < $count; $i++) {
-            $filerecord['filename'] = 'smallfile' . $i . '.dat';
-
-            // Generate random binary data (different for each file so it
-            // doesn't compress unrealistically).
-            $data = self::get_random_binary(self::$paramsmallfilesize[$this->size]);
-
-            $fs->create_file_from_string($filerecord, $data);
-            $this->dot($i, $count);
-        }
-
-        $this->end_log();
-    }
-
-    /**
-     * Creates a string of random binary data. The start of the string includes
-     * the current time, in an attempt to avoid large-scale repetition.
-     *
-     * @param int $length Number of bytes
-     * @return Random data
-     */
-    private static function get_random_binary($length) {
-        $data = microtime(true);
-        if (strlen($data) > $length) {
-            // Use last digits of data.
-            return substr($data, -$length);
-        }
-        $length -= strlen($data);
-        for ($j=0; $j < $length; $j++) {
-            $data .= chr(rand(1, 255));
-        }
-        return $data;
-    }
-
-    /**
-     * Creates a number of resource activities with one big file each.
-     */
-    private function create_big_files() {
-        global $CFG;
-
-        // Work out how many files and how many blocks to use (up to 64KB).
-        $count = self::$parambigfilecount[$this->size];
-        $blocks = ceil(self::$parambigfilesize[$this->size] / 65536);
-        $blocksize = floor(self::$parambigfilesize[$this->size] / $blocks);
-
-        $this->log('createbigfiles', $count, true);
-
-        // Prepare temp area.
-        $tempfolder = make_temp_directory('tool_generator');
-        $tempfile = $tempfolder . '/' . rand();
-
-        // Create resources and files.
-        $fs = get_file_storage();
-        $resourcegenerator = $this->generator->get_plugin_generator('mod_resource');
-        for ($i = 0; $i < $count; $i++) {
-            // Create resource.
-            $record = array('course' => $this->course->id,
-                    'name' => get_string('bigfile', 'tool_generator', $i));
-            $options = array('section' => $this->get_random_section());
-            $resource = $resourcegenerator->create_instance($record, $options);
-
-            // Write file.
-            $handle = fopen($tempfile, 'w');
-            if (!$handle) {
-                throw new coding_exception('Failed to open temporary file');
-            }
-            for ($j = 0; $j < $blocks; $j++) {
-                $data = self::get_random_binary($blocksize);
-                fwrite($handle, $data);
-                $this->dot($i * $blocks + $j, $count * $blocks);
-            }
-            fclose($handle);
-
-            // Add file.
-            $context = context_module::instance($resource->cmid);
-            $filerecord = array('component' => 'mod_resource', 'filearea' => 'content',
-                    'contextid' => $context->id, 'itemid' => 0, 'filepath' => '/',
-                    'filename' => 'bigfile' . $i . '.dat');
-            $fs->create_file_from_pathname($filerecord, $tempfile);
-        }
-
-        unlink($tempfile);
-        $this->end_log();
-    }
-
-    /**
-     * Creates one forum activity with a bunch of posts.
-     */
-    private function create_forum() {
-        global $DB;
-
-        $discussions = self::$paramforumdiscussions[$this->size];
-        $posts = self::$paramforumposts[$this->size];
-        $totalposts = $discussions * $posts;
-
-        $this->log('createforum', $totalposts, true);
-
-        // Create empty forum.
-        $forumgenerator = $this->generator->get_plugin_generator('mod_forum');
-        $record = array('course' => $this->course->id,
-                'name' => get_string('pluginname', 'forum'));
-        $options = array('section' => 0);
-        $forum = $forumgenerator->create_instance($record, $options);
-
-        // Add discussions and posts.
-        $sofar = 0;
-        for ($i=0; $i < $discussions; $i++) {
-            $record = array('forum' => $forum->id, 'course' => $this->course->id,
-                    'userid' => $this->get_random_user());
-            $discussion = $forumgenerator->create_discussion($record);
-            $parentid = $DB->get_field('forum_posts', 'id', array('discussion' => $discussion->id), MUST_EXIST);
-            $sofar++;
-            for ($j=0; $j < $posts - 1; $j++, $sofar++) {
-                $record = array('discussion' => $discussion->id,
-                        'userid' => $this->get_random_user(), 'parent' => $parentid);
-                $forumgenerator->create_post($record);
-                $this->dot($sofar, $totalposts);
-            }
-        }
-
-        $this->end_log();
-    }
-
-    /**
-     * Gets a random section number.
-     *
-     * @return int A section number from 1 to the number of sections
-     */
-    private function get_random_section() {
-        return rand(1, self::$paramsections[$this->size]);
-    }
-
-    /**
-     * Gets a random user id.
-     *
-     * @return int A user id for a random created user
-     */
-    private function get_random_user() {
-        return $this->userids[rand(1, self::$paramusers[$this->size])];
-    }
-
     /**
      * Displays information as part of progress.
      * @param string $langstring Part of langstring (after progress_)
      * @param mixed $a Optional lang string parameters
      * @param bool $leaveopen If true, doesn't close LI tag (ready for dots)
      */
-    private function log($langstring, $a = null, $leaveopen = false) {
+    protected function log($langstring, $a = null, $leaveopen = false) {
         if (!$this->progress) {
             return;
         }
@@ -564,7 +149,7 @@ class tool_generator_backend {
      * @param int $number Number of completed items
      * @param int $total Total number of items to complete
      */
-    private function dot($number, $total) {
+    protected function dot($number, $total) {
         if (!$this->progress) {
             return;
         }
@@ -592,7 +177,7 @@ class tool_generator_backend {
     /**
      * Ends a log string that was started using log function with $leaveopen.
      */
-    private function end_log() {
+    protected function end_log() {
         if (!$this->progress) {
             return;
         }
@@ -603,4 +188,5 @@ class tool_generator_backend {
             echo html_writer::end_tag('li');
         }
     }
+
 }
diff --git a/admin/tool/generator/classes/course_backend.php b/admin/tool/generator/classes/course_backend.php
new file mode 100644 (file)
index 0000000..07e1e7b
--- /dev/null
@@ -0,0 +1,507 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * tool_generator course backend code.
+ *
+ * @package tool_generator
+ * @copyright 2013 The Open University
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Backend code for the 'make large course' tool.
+ *
+ * @package tool_generator
+ * @copyright 2013 The Open University
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class tool_generator_course_backend extends tool_generator_backend {
+    /**
+     * @var array Number of sections in course
+     */
+    private static $paramsections = array(1, 10, 100, 500, 1000, 2000);
+    /**
+     * @var array Number of Page activities in course
+     */
+    private static $parampages = array(1, 50, 200, 1000, 5000, 10000);
+    /**
+     * @var array Number of students enrolled in course
+     */
+    private static $paramusers = array(1, 100, 1000, 10000, 50000, 100000);
+    /**
+     * Total size of small files: 1KB, 1MB, 10MB, 100MB, 1GB, 2GB.
+     *
+     * @var array Number of small files created in a single file activity
+     */
+    private static $paramsmallfilecount = array(1, 64, 128, 1024, 16384, 32768);
+    /**
+     * @var array Size of small files (to make the totals into nice numbers)
+     */
+    private static $paramsmallfilesize = array(1024, 16384, 81920, 102400, 65536, 65536);
+    /**
+     * Total size of big files: 8KB, 8MB, 80MB, 800MB, 8GB, 16GB.
+     *
+     * @var array Number of big files created as individual file activities
+     */
+    private static $parambigfilecount = array(1, 2, 5, 10, 10, 10);
+    /**
+     * @var array Size of each large file
+     */
+    private static $parambigfilesize = array(8192, 4194304, 16777216, 83886080,
+            858993459, 1717986918);
+    /**
+     * @var array Number of forum discussions
+     */
+    private static $paramforumdiscussions = array(1, 10, 100, 500, 1000, 2000);
+    /**
+     * @var array Number of forum posts per discussion
+     */
+    private static $paramforumposts = array(2, 2, 5, 10, 10, 10);
+
+    /**
+     * @var string Course shortname
+     */
+    private $shortname;
+
+    /**
+     * @var testing_data_generator Data generator
+     */
+    protected $generator;
+
+    /**
+     * @var stdClass Course object
+     */
+    private $course;
+
+    /**
+     * @var array Array from test user number (1...N) to userid in database
+     */
+    private $userids;
+
+    /**
+     * Constructs object ready to create course.
+     *
+     * @param string $shortname Course shortname
+     * @param int $size Size as numeric index
+     * @param bool $fixeddataset To use fixed or random data
+     * @param bool $progress True if progress information should be displayed
+     * @return int Course id
+     */
+    public function __construct($shortname, $size, $fixeddataset = false, $progress = true) {
+
+        // Set parameters.
+        $this->shortname = $shortname;
+
+        parent::__construct($size, $fixeddataset, $progress);
+    }
+
+    /**
+     * Gets a list of size choices supported by this backend.
+     *
+     * @return array List of size (int) => text description for display
+     */
+    public static function get_size_choices() {
+        $options = array();
+        for ($size = self::MIN_SIZE; $size <= self::MAX_SIZE; $size++) {
+            $options[$size] = get_string('coursesize_' . $size, 'tool_generator');
+        }
+        return $options;
+    }
+
+    /**
+     * Checks that a shortname is available (unused).
+     *
+     * @param string $shortname Proposed course shortname
+     * @return string An error message if the name is unavailable or '' if OK
+     */
+    public static function check_shortname_available($shortname) {
+        global $DB;
+        $fullname = $DB->get_field('course', 'fullname',
+                array('shortname' => $shortname), IGNORE_MISSING);
+        if ($fullname !== false) {
+            // I wanted to throw an exception here but it is not possible to
+            // use strings from moodle.php in exceptions, and I didn't want
+            // to duplicate the string in tool_generator, so I changed this to
+            // not use exceptions.
+            return get_string('shortnametaken', 'moodle', $fullname);
+        }
+        return '';
+    }
+
+    /**
+     * Runs the entire 'make' process.
+     *
+     * @return int Course id
+     */
+    public function make() {
+        global $DB, $CFG;
+        require_once($CFG->dirroot . '/lib/phpunit/classes/util.php');
+
+        raise_memory_limit(MEMORY_EXTRA);
+
+        if ($this->progress && !CLI_SCRIPT) {
+            echo html_writer::start_tag('ul');
+        }
+
+        $entirestart = microtime(true);
+
+        // Start transaction.
+        $transaction = $DB->start_delegated_transaction();
+
+        // Get generator.
+        $this->generator = phpunit_util::get_data_generator();
+
+        // Make course.
+        $this->course = $this->create_course();
+        $this->create_users();
+        $this->create_pages();
+        $this->create_small_files();
+        $this->create_big_files();
+        $this->create_forum();
+
+        // Log total time.
+        $this->log('coursecompleted', round(microtime(true) - $entirestart, 1));
+
+        if ($this->progress && !CLI_SCRIPT) {
+            echo html_writer::end_tag('ul');
+        }
+
+        // Commit transaction and finish.
+        $transaction->allow_commit();
+        return $this->course->id;
+    }
+
+    /**
+     * Creates the actual course.
+     *
+     * @return stdClass Course record
+     */
+    private function create_course() {
+        $this->log('createcourse', $this->shortname);
+        $courserecord = array('shortname' => $this->shortname,
+                'fullname' => get_string('fullname', 'tool_generator',
+                    array('size' => get_string('shortsize_' . $this->size, 'tool_generator'))),
+                'numsections' => self::$paramsections[$this->size]);
+        return $this->generator->create_course($courserecord, array('createsections' => true));
+    }
+
+    /**
+     * Creates a number of user accounts and enrols them on the course.
+     * Note: Existing user accounts that were created by this system are
+     * reused if available.
+     */
+    private function create_users() {
+        global $DB;
+
+        // Work out total number of users.
+        $count = self::$paramusers[$this->size];
+
+        // Get existing users in order. We will 'fill up holes' in this up to
+        // the required number.
+        $this->log('checkaccounts', $count);
+        $nextnumber = 1;
+        $rs = $DB->get_recordset_select('user', $DB->sql_like('username', '?'),
+                array('tool_generator_%'), 'username', 'id, username');
+        foreach ($rs as $rec) {
+            // Extract number from username.
+            $matches = array();
+            if (!preg_match('~^tool_generator_([0-9]{6})$~', $rec->username, $matches)) {
+                continue;
+            }
+            $number = (int)$matches[1];
+
+            // Create missing users in range up to this.
+            if ($number != $nextnumber) {
+                $this->create_user_accounts($nextnumber, min($number - 1, $count));
+            } else {
+                $this->userids[$number] = (int)$rec->id;
+            }
+
+            // Stop if we've got enough users.
+            $nextnumber = $number + 1;
+            if ($number >= $count) {
+                break;
+            }
+        }
+        $rs->close();
+
+        // Create users from end of existing range.
+        if ($nextnumber <= $count) {
+            $this->create_user_accounts($nextnumber, $count);
+        }
+
+        // Assign all users to course.
+        $this->log('enrol', $count, true);
+
+        $enrolplugin = enrol_get_plugin('manual');
+        $instances = enrol_get_instances($this->course->id, true);
+        foreach ($instances as $instance) {
+            if ($instance->enrol === 'manual') {
+                break;
+            }
+        }
+        if ($instance->enrol !== 'manual') {
+            throw new coding_exception('No manual enrol plugin in course');
+        }
+        $role = $DB->get_record('role', array('shortname' => 'student'), '*', MUST_EXIST);
+
+        for ($number = 1; $number <= $count; $number++) {
+            // Enrol user.
+            $enrolplugin->enrol_user($instance, $this->userids[$number], $role->id);
+            $this->dot($number, $count);
+        }
+
+        // Sets the pointer at the beginning to be aware of the users we use.
+        reset($this->userids);
+
+        $this->end_log();
+    }
+
+    /**
+     * Creates user accounts with a numeric range.
+     *
+     * @param int $first Number of first user
+     * @param int $last Number of last user
+     */
+    private function create_user_accounts($first, $last) {
+        $this->log('createaccounts', (object)array('from' => $first, 'to' => $last), true);
+        $count = $last - $first + 1;
+        $done = 0;
+        for ($number = $first; $number <= $last; $number++, $done++) {
+            // Work out username with 6-digit number.
+            $textnumber = (string)$number;
+            while (strlen($textnumber) < 6) {
+                $textnumber = '0' . $textnumber;
+            }
+            $username = 'tool_generator_' . $textnumber;
+
+            // Create user account.
+            $record = array('firstname' => get_string('firstname', 'tool_generator'),
+                    'lastname' => $number, 'username' => $username);
+            $user = $this->generator->create_user($record);
+            $this->userids[$number] = (int)$user->id;
+            $this->dot($done, $count);
+        }
+        $this->end_log();
+    }
+
+    /**
+     * Creates a number of Page activities.
+     */
+    private function create_pages() {
+        // Set up generator.
+        $pagegenerator = $this->generator->get_plugin_generator('mod_page');
+
+        // Create pages.
+        $number = self::$parampages[$this->size];
+        $this->log('createpages', $number, true);
+        for ($i=0; $i<$number; $i++) {
+            $record = array('course' => $this->course->id);
+            $options = array('section' => $this->get_target_section());
+            $pagegenerator->create_instance($record, $options);
+            $this->dot($i, $number);
+        }
+
+        $this->end_log();
+    }
+
+    /**
+     * Creates one resource activity with a lot of small files.
+     */
+    private function create_small_files() {
+        $count = self::$paramsmallfilecount[$this->size];
+        $this->log('createsmallfiles', $count, true);
+
+        // Create resource with default textfile only.
+        $resourcegenerator = $this->generator->get_plugin_generator('mod_resource');
+        $record = array('course' => $this->course->id,
+                'name' => get_string('smallfiles', 'tool_generator'));
+        $options = array('section' => 0);
+        $resource = $resourcegenerator->create_instance($record, $options);
+
+        // Add files.
+        $fs = get_file_storage();
+        $context = context_module::instance($resource->cmid);
+        $filerecord = array('component' => 'mod_resource', 'filearea' => 'content',
+                'contextid' => $context->id, 'itemid' => 0, 'filepath' => '/');
+        for ($i = 0; $i < $count; $i++) {
+            $filerecord['filename'] = 'smallfile' . $i . '.dat';
+
+            // Generate random binary data (different for each file so it
+            // doesn't compress unrealistically).
+            $data = self::get_random_binary(self::$paramsmallfilesize[$this->size]);
+
+            $fs->create_file_from_string($filerecord, $data);
+            $this->dot($i, $count);
+        }
+
+        $this->end_log();
+    }
+
+    /**
+     * Creates a string of random binary data. The start of the string includes
+     * the current time, in an attempt to avoid large-scale repetition.
+     *
+     * @param int $length Number of bytes
+     * @return Random data
+     */
+    private static function get_random_binary($length) {
+        $data = microtime(true);
+        if (strlen($data) > $length) {
+            // Use last digits of data.
+            return substr($data, -$length);
+        }
+        $length -= strlen($data);
+        for ($j=0; $j < $length; $j++) {
+            $data .= chr(rand(1, 255));
+        }
+        return $data;
+    }
+
+    /**
+     * Creates a number of resource activities with one big file each.
+     */
+    private function create_big_files() {
+        global $CFG;
+
+        // Work out how many files and how many blocks to use (up to 64KB).
+        $count = self::$parambigfilecount[$this->size];
+        $blocks = ceil(self::$parambigfilesize[$this->size] / 65536);
+        $blocksize = floor(self::$parambigfilesize[$this->size] / $blocks);
+
+        $this->log('createbigfiles', $count, true);
+
+        // Prepare temp area.
+        $tempfolder = make_temp_directory('tool_generator');
+        $tempfile = $tempfolder . '/' . rand();
+
+        // Create resources and files.
+        $fs = get_file_storage();
+        $resourcegenerator = $this->generator->get_plugin_generator('mod_resource');
+        for ($i = 0; $i < $count; $i++) {
+            // Create resource.
+            $record = array('course' => $this->course->id,
+                    'name' => get_string('bigfile', 'tool_generator', $i));
+            $options = array('section' => $this->get_target_section());
+            $resource = $resourcegenerator->create_instance($record, $options);
+
+            // Write file.
+            $handle = fopen($tempfile, 'w');
+            if (!$handle) {
+                throw new coding_exception('Failed to open temporary file');
+            }
+            for ($j = 0; $j < $blocks; $j++) {
+                $data = self::get_random_binary($blocksize);
+                fwrite($handle, $data);
+                $this->dot($i * $blocks + $j, $count * $blocks);
+            }
+            fclose($handle);
+
+            // Add file.
+            $context = context_module::instance($resource->cmid);
+            $filerecord = array('component' => 'mod_resource', 'filearea' => 'content',
+                    'contextid' => $context->id, 'itemid' => 0, 'filepath' => '/',
+                    'filename' => 'bigfile' . $i . '.dat');
+            $fs->create_file_from_pathname($filerecord, $tempfile);
+        }
+
+        unlink($tempfile);
+        $this->end_log();
+    }
+
+    /**
+     * Creates one forum activity with a bunch of posts.
+     */
+    private function create_forum() {
+        global $DB;
+
+        $discussions = self::$paramforumdiscussions[$this->size];
+        $posts = self::$paramforumposts[$this->size];
+        $totalposts = $discussions * $posts;
+
+        $this->log('createforum', $totalposts, true);
+
+        // Create empty forum.
+        $forumgenerator = $this->generator->get_plugin_generator('mod_forum');
+        $record = array('course' => $this->course->id,
+                'name' => get_string('pluginname', 'forum'));
+        $options = array('section' => 0);
+        $forum = $forumgenerator->create_instance($record, $options);
+
+        // Add discussions and posts.
+        $sofar = 0;
+        for ($i=0; $i < $discussions; $i++) {
+            $record = array('forum' => $forum->id, 'course' => $this->course->id,
+                    'userid' => $this->get_target_user());
+            $discussion = $forumgenerator->create_discussion($record);
+            $parentid = $DB->get_field('forum_posts', 'id', array('discussion' => $discussion->id), MUST_EXIST);
+            $sofar++;
+            for ($j=0; $j < $posts - 1; $j++, $sofar++) {
+                $record = array('discussion' => $discussion->id,
+                        'userid' => $this->get_target_user(), 'parent' => $parentid);
+                $forumgenerator->create_post($record);
+                $this->dot($sofar, $totalposts);
+            }
+        }
+
+        $this->end_log();
+    }
+
+    /**
+     * Gets a section number.
+     *
+     * Depends on $this->fixeddataset.
+     *
+     * @return int A section number from 1 to the number of sections
+     */
+    private function get_target_section() {
+
+        if (!$this->fixeddataset) {
+            $key = rand(1, self::$paramsections[$this->size]);
+        } else {
+            // Using section 1.
+            $key = 1;
+        }
+
+        return $key;
+    }
+
+    /**
+     * Gets a user id.
+     *
+     * Depends on $this->fixeddataset.
+     *
+     * @return int A user id for a random created user
+     */
+    private function get_target_user() {
+
+        if (!$this->fixeddataset) {
+            $userid = $this->userids[rand(1, self::$paramusers[$this->size])];
+        } else if ($userid = current($this->userids)) {
+            // Moving pointer to the next user.
+            next($this->userids);
+        } else {
+            // Returning to the beginning if we reached the end.
+            $userid = reset($this->userids);
+        }
+
+        return $userid;
+    }
+
+}
index 25c8350..879364d 100644 (file)
@@ -31,8 +31,8 @@ class tool_generator_make_form extends moodleform {
         $mform = $this->_form;
 
         $mform->addElement('select', 'size', get_string('size', 'tool_generator'),
-                tool_generator_backend::get_size_choices());
-        $mform->setDefault('size', tool_generator_backend::DEFAULT_SIZE);
+                tool_generator_course_backend::get_size_choices());
+        $mform->setDefault('size', tool_generator_course_backend::DEFAULT_SIZE);
 
         $mform->addElement('text', 'shortname', get_string('shortnamecourse'));
         $mform->addRule('shortname', get_string('missingshortname'), 'required', null, 'client');
@@ -48,7 +48,7 @@ class tool_generator_make_form extends moodleform {
         // Check course doesn't already exist.
         if (!empty($data['shortname'])) {
             // Check shortname.
-            $error =  tool_generator_backend::check_shortname_available($data['shortname']);
+            $error =  tool_generator_course_backend::check_shortname_available($data['shortname']);
             if ($error) {
                 $errors['shortname'] = $error;
             }
diff --git a/admin/tool/generator/classes/site_backend.php b/admin/tool/generator/classes/site_backend.php
new file mode 100644 (file)
index 0000000..01bde97
--- /dev/null
@@ -0,0 +1,203 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * tool_generator site backend.
+ *
+ * @package tool_generator
+ * @copyright 2013 David Monllaó
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Backend code for the site generator.
+ *
+ * @package tool_generator
+ * @copyright 2013 David Monllaó
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class tool_generator_site_backend extends tool_generator_backend {
+
+    /**
+     * @var string The course's shortname prefix.
+     */
+    const SHORTNAMEPREFIX = 'testcourse_';
+
+    /**
+     * @var bool If the debugging level checking was skipped.
+     */
+    protected $bypasscheck;
+
+    /**
+     * @var array Multidimensional array where the first level is the course size and the second the site size.
+     */
+    protected static $sitecourses = array(
+        array(2, 8, 64, 256, 1024, 4096),
+        array(1, 4, 8, 16, 32, 64),
+        array(0, 0, 1, 4, 8, 16),
+        array(0, 0, 0, 1, 0, 0),
+        array(0, 0, 0, 0, 1, 0),
+        array(0, 0, 0, 0, 0, 1)
+    );
+
+    /**
+     * Constructs object ready to make the site.
+     *
+     * @param int $size Size as numeric index
+     * @param bool $bypasscheck If debugging level checking was skipped.
+     * @param bool $fixeddataset To use fixed or random data
+     * @param bool $progress True if progress information should be displayed
+     * @return int Course id
+     */
+    public function __construct($size, $bypasscheck, $fixeddataset = false, $progress = true) {
+
+        // Set parameters.
+        $this->bypasscheck = $bypasscheck;
+
+        parent::__construct($size, $fixeddataset, $progress);
+    }
+
+    /**
+     * Gets a list of size choices supported by this backend.
+     *
+     * @return array List of size (int) => text description for display
+     */
+    public static function get_size_choices() {
+        $options = array();
+        for ($size = self::MIN_SIZE; $size <= self::MAX_SIZE; $size++) {
+            $options[$size] = get_string('sitesize_' . $size, 'tool_generator');
+        }
+        return $options;
+    }
+
+    /**
+     * Runs the entire 'make' process.
+     *
+     * @return int Course id
+     */
+    public function make() {
+        global $DB, $CFG;
+
+        raise_memory_limit(MEMORY_EXTRA);
+
+        if ($this->progress && !CLI_SCRIPT) {
+            echo html_writer::start_tag('ul');
+        }
+
+        $entirestart = microtime(true);
+
+        // Create courses.
+        $prevchdir = getcwd();
+        chdir($CFG->dirroot);
+        $ncourse = $this->get_last_testcourse_id();
+        foreach (self::$sitecourses as $coursesize => $ncourses) {
+            for ($i = 1; $i <= $ncourses[$this->size]; $i++) {
+                // Non language-dependant shortname.
+                $ncourse++;
+                $this->run_create_course(self::SHORTNAMEPREFIX . $ncourse, $coursesize);
+            }
+        }
+        chdir($prevchdir);
+
+        // Store last course id to return it (will be the bigger one).
+        $lastcourseid = $DB->get_field('course', 'id', array('shortname' => self::SHORTNAMEPREFIX . $ncourse));
+
+        // Log total time.
+        $this->log('sitecompleted', round(microtime(true) - $entirestart, 1));
+
+        if ($this->progress && !CLI_SCRIPT) {
+            echo html_writer::end_tag('ul');
+        }
+
+        return $lastcourseid;
+    }
+
+    /**
+     * Creates a course with the specified shortname, coursesize and the provided maketestsite options.
+     *
+     * @param string $shortname The course shortname
+     * @param int $coursesize One of the possible course sizes.
+     * @return void
+     */
+    protected function run_create_course($shortname, $coursesize) {
+
+        // We are in $CFG->dirroot.
+        $command = 'php admin/tool/generator/cli/maketestcourse.php';
+
+        $options = array(
+            '--shortname="' . $shortname . '"',
+            '--size="' . get_string('shortsize_' . $coursesize, 'tool_generator') . '"'
+        );
+
+        if (!$this->progress) {
+            $options[] = '--quiet';
+        }
+
+        // Extend options.
+        $optionstoextend = array(
+            'fixeddataset' => 'fixeddataset',
+            'bypasscheck' => 'bypasscheck',
+        );
+
+        // Getting an options string.
+        foreach ($optionstoextend as $attribute => $option) {
+            if (!empty($this->{$attribute})) {
+                $options[] = '--' . $option;
+            }
+        }
+        $options = implode(' ', $options);
+        if ($this->progress) {
+            system($command . ' ' . $options, $exitcode);
+        } else {
+            passthru($command . ' ' . $options, $exitcode);
+        }
+
+        if ($exitcode != 0) {
+            exit($exitcode);
+        }
+    }
+
+    /**
+     * Obtains the last unique sufix (numeric) using the test course prefix.
+     *
+     * @return int The last generated numeric value.
+     */
+    protected function get_last_testcourse_id() {
+        global $DB;
+
+        $params = array();
+        $params['shortnameprefix'] = $DB->sql_like_escape(self::SHORTNAMEPREFIX) . '%';
+        $like = $DB->sql_like('shortname', ':shortnameprefix');
+
+        if (!$testcourses = $DB->get_records_select('course', $like, $params, 'shortname DESC')) {
+            return 0;
+        }
+
+        // They come ordered by shortname DESC, so non-numeric values will be the first ones.
+        foreach ($testcourses as $testcourse) {
+            $sufix = substr($testcourse->shortname, strlen(self::SHORTNAMEPREFIX));
+            if (is_numeric($sufix)) {
+                return $sufix;
+            }
+        }
+
+        // If all sufixes are not numeric this is the fist make test site run.
+        return 0;
+    }
+
+}
index b646e2f..407a58f 100644 (file)
@@ -34,6 +34,7 @@ list($options, $unrecognized) = cli_get_params(
         'help' => false,
         'shortname' => false,
         'size' => false,
+        'fixeddataset' => false,
         'bypasscheck' => false,
         'quiet' => false
     ),
@@ -53,6 +54,7 @@ level.
 Options:
 --shortname    Shortname of course to create (required)
 --size         Size of course to create XS, S, M, L, XL, or XXL (required)
+--fixeddataset Use a fixed data set instead of randomly generated data
 --bypasscheck  Bypasses the developer-mode check (be careful!)
 --quiet        Do not show any output
 
@@ -73,16 +75,17 @@ if (empty($options['bypasscheck']) && !debugging('', DEBUG_DEVELOPER)) {
 // Get options.
 $shortname = $options['shortname'];
 $sizename = $options['size'];
+$fixeddataset = $options['fixeddataset'];
 
 // Check size.
 try {
-    $size = tool_generator_backend::size_for_name($sizename);
+    $size = tool_generator_course_backend::size_for_name($sizename);
 } catch (coding_exception $e) {
     cli_error("Invalid size ($sizename). Use --help for help.");
 }
 
 // Check shortname.
-if ($error = tool_generator_backend::check_shortname_available($shortname)) {
+if ($error = tool_generator_course_backend::check_shortname_available($shortname)) {
     cli_error($error);
 }
 
@@ -90,5 +93,5 @@ if ($error = tool_generator_backend::check_shortname_available($shortname)) {
 session_set_user(get_admin());
 
 // Do backend code to generate course.
-$backend = new tool_generator_backend($shortname, $size, empty($options['quiet']));
+$backend = new tool_generator_course_backend($shortname, $size, $fixeddataset, empty($options['quiet']));
 $id = $backend->make();
diff --git a/admin/tool/generator/cli/maketestsite.php b/admin/tool/generator/cli/maketestsite.php
new file mode 100644 (file)
index 0000000..bc91d7d
--- /dev/null
@@ -0,0 +1,95 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * CLI interface for creating a test site.
+ *
+ * @package tool_generator
+ * @copyright 2013 David Monllaó
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define('CLI_SCRIPT', true);
+define('NO_OUTPUT_BUFFERING', true);
+
+require(__DIR__ . '/../../../../config.php');
+require_once($CFG->libdir. '/clilib.php');
+
+// CLI options.
+list($options, $unrecognized) = cli_get_params(
+    array(
+        'help' => false,
+        'size' => false,
+        'fixeddataset' => false,
+        'bypasscheck' => false,
+        'quiet' => false
+    ),
+    array(
+        'h' => 'help'
+    )
+);
+
+$sitesizes = '* ' . implode(PHP_EOL . '* ', tool_generator_site_backend::get_size_choices());
+
+// Display help.
+if (!empty($options['help']) || empty($options['size'])) {
+    echo "
+Utility to generate a standard test site data set.
+
+Not for use on live sites; only normally works if debugging is set to DEVELOPER
+level.
+
+Consider that, depending on the size you select, this CLI tool can really generate a lot of data, aproximated sizes:
+
+$sitesizes
+
+Options:
+--size         Size of the generated site, this value affects the number of courses and their size. Accepted values: XS, S, M, L, XL, or XXL (required)
+--fixeddataset Use a fixed data set instead of randomly generated data
+--bypasscheck  Bypasses the developer-mode check (be careful!)
+--quiet        Do not show any output
+
+-h, --help     Print out this help
+
+Example from Moodle root directory:
+\$ php admin/tool/generator/cli/maketestsite.php --size=S
+";
+    // Exit with error unless we're showing this because they asked for it.
+    exit(empty($options['help']) ? 1 : 0);
+}
+
+// Check debugging is set to developer level.
+if (empty($options['bypasscheck']) && !$CFG->debugdeveloper) {
+    cli_error(get_string('error_notdebugging', 'tool_generator'));
+}
+
+// Get options.
+$sizename = $options['size'];
+$fixeddataset = $options['fixeddataset'];
+
+// Check size.
+try {
+    $size = tool_generator_site_backend::size_for_name($sizename);
+} catch (coding_exception $e) {
+    cli_error("Invalid size ($sizename). Use --help for help.");
+}
+
+// Switch to admin user account.
+session_set_user(get_admin());
+
+// Do backend code to generate site.
+$backend = new tool_generator_site_backend($size, $options['bypasscheck'], $fixeddataset, empty($options['quiet']));
+$backend->make();
index 103a4fd..a204ce8 100644 (file)
  */
 
 $string['bigfile'] = 'Big file {$a}';
+$string['coursesize_0'] = 'XS (~10KB; create in ~1 second)';
+$string['coursesize_1'] = 'S (~10MB; create in ~30 seconds)';
+$string['coursesize_2'] = 'M (~100MB; create in ~5 minutes)';
+$string['coursesize_3'] = 'L (~1GB; create in ~1 hour)';
+$string['coursesize_4'] = 'XL (~10GB; create in ~4 hours)';
+$string['coursesize_5'] = 'XXL (~20GB; create in ~8 hours)';
 $string['createcourse'] = 'Create course';
 $string['creating'] = 'Creating course';
 $string['done'] = 'done ({$a}s)';
@@ -48,27 +54,28 @@ $string['error_notdebugging'] = 'Not available on this server because debugging
 $string['firstname'] = 'Test course user';
 $string['fullname'] = 'Test course: {$a->size}';
 $string['maketestcourse'] = 'Make test course';
-$string['pluginname'] = 'Random course generator';
+$string['pluginname'] = 'Development data generator';
 $string['progress_createcourse'] = 'Creating course {$a}';
 $string['progress_checkaccounts'] = 'Checking user accounts ({$a})';
+$string['progress_coursecompleted'] = 'Course completed ({$a}s)';
 $string['progress_createaccounts'] = 'Creating user accounts ({$a->from} - {$a->to})';
 $string['progress_createbigfiles'] = 'Creating big files ({$a})';
 $string['progress_createforum'] = 'Creating forum ({$a} posts)';
 $string['progress_createpages'] = 'Creating pages ({$a})';
 $string['progress_createsmallfiles'] = 'Creating small files ({$a})';
 $string['progress_enrol'] = 'Enrolling users into course ({$a})';
-$string['progress_complete'] = 'Complete ({$a}s)';
+$string['progress_sitecompleted'] = 'Site completed ({$a}s)';
 $string['shortsize_0'] = 'XS';
 $string['shortsize_1'] = 'S';
 $string['shortsize_2'] = 'M';
 $string['shortsize_3'] = 'L';
 $string['shortsize_4'] = 'XL';
 $string['shortsize_5'] = 'XXL';
+$string['sitesize_0'] = 'XS (~10MB; 3 courses, created in ~30 seconds)';
+$string['sitesize_1'] = 'S (~50MB; 8 courses, created in ~2 minutes)';
+$string['sitesize_2'] = 'M (~200MB; 73 courses, created in ~10 minutes)';
+$string['sitesize_3'] = 'L (~1\'5GB; 277 courses, created in ~1\'5 hours)';
+$string['sitesize_4'] = 'XL (~10GB; 1065 courses, created in ~5 hours)';
+$string['sitesize_5'] = 'XXL (~20GB; 4177 courses, created in ~10 hours)';
 $string['size'] = 'Size of course';
-$string['size_0'] = 'XS (~10KB; create in ~1 second)';
-$string['size_1'] = 'S (~10MB; create in ~30 seconds)';
-$string['size_2'] = 'M (~100MB; create in ~5 minutes)';
-$string['size_3'] = 'L (~1GB; create in ~1 hour)';
-$string['size_4'] = 'XL (~10GB; create in ~4 hours)';
-$string['size_5'] = 'XXL (~20GB; create in ~8 hours)';
 $string['smallfiles'] = 'Small files';
index f3ff9f7..82af097 100644 (file)
@@ -55,7 +55,7 @@ $mform = new tool_generator_make_form('maketestcourse.php');
 if ($data = $mform->get_data()) {
     // Do actual work.
     echo $OUTPUT->heading(get_string('creating', 'tool_generator'));
-    $backend = new tool_generator_backend($data->shortname, $data->size);
+    $backend = new tool_generator_course_backend($data->shortname, $data->size);
     $id = $backend->make();
 
     echo html_writer::div(
index 3b2244d..b8637f4 100644 (file)
@@ -35,7 +35,7 @@ class tool_generator_maketestcourse_testcase extends advanced_testcase {
         $this->setAdminUser();
 
         // Create the XS course.
-        $backend = new tool_generator_backend('TOOL_MAKELARGECOURSE_XS', 0, false);
+        $backend = new tool_generator_course_backend('TOOL_MAKELARGECOURSE_XS', 0, false, false);
         $courseid = $backend->make();
 
         // Get course details.
@@ -107,4 +107,48 @@ class tool_generator_maketestcourse_testcase extends advanced_testcase {
                     fd.forum = ?", array($forum->instance));
         $this->assertEquals(2, $posts);
     }
+
+    /**
+     * Creates an small test course with fixed data set and checks the used sections and users.
+     */
+    public function test_fixed_data_set() {
+        global $DB;
+
+        $this->resetAfterTest();
+        $this->setAdminUser();
+
+        // Create the S course (more sections and activities than XS).
+        $backend = new tool_generator_course_backend('TOOL_S_COURSE_1', 1, true, false);
+        $courseid = $backend->make();
+
+        // Get course details.
+        $course = get_course($courseid);
+        $modinfo = get_fast_modinfo($course);
+
+        // Check module instances belongs to section 1.
+        $instances = $modinfo->get_instances_of('page');
+        $npageinstances = count($instances);
+        foreach ($instances as $instance) {
+            $this->assertEquals(1, $instance->sectionnum);
+        }
+
+        // Users that started discussions are the same.
+        $forums = $modinfo->get_instances_of('forum');
+        $nforuminstances = count($forums);
+        $discussions = forum_get_discussions(reset($forums), 'd.timemodified ASC');
+        $lastusernumber = 0;
+        $discussionstarters = array();
+        foreach ($discussions as $discussion) {
+            $usernumber = intval($discussion->lastname);
+
+            // Checks that the users are odd numbers.
+            $this->assertEquals(1, $usernumber % 2);
+
+            // Checks that the users follows an increasing order.
+            $this->assertGreaterThan($lastusernumber, $usernumber);
+            $lastusernumber = $usernumber;
+            $discussionstarters[$discussion->userid] = $discussion->subject;
+        }
+
+    }
 }
index 66aa662..3733d98 100644 (file)
@@ -24,6 +24,6 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2013080700;
-$plugin->requires = 2013080200;
+$plugin->version = 2013090200;
+$plugin->requires = 2013090200;
 $plugin->component = 'tool_generator';
index c052d1c..7949d94 100644 (file)
@@ -27,6 +27,7 @@ require('../../../config.php');
 require_once($CFG->libdir.'/adminlib.php');
 require_once($CFG->libdir.'/csvlib.class.php');
 require_once($CFG->dirroot.'/user/profile/lib.php');
+require_once($CFG->dirroot.'/user/lib.php');
 require_once($CFG->dirroot.'/group/lib.php');
 require_once($CFG->dirroot.'/cohort/lib.php');
 require_once('locallib.php');
@@ -654,9 +655,8 @@ if ($formdata = $mform2->is_cancelled()) {
             }
 
             if ($doupdate or $existinguser->password !== $oldpw) {
-                // we want only users that were really updated
-
-                $DB->update_record('user', $existinguser);
+                // We want only users that were really updated.
+                user_update_user($existinguser, false);
 
                 $upt->track('status', $struserupdated);
                 $usersupdated++;
@@ -668,8 +668,6 @@ if ($formdata = $mform2->is_cancelled()) {
                     profile_save_data($existinguser);
                 }
 
-                events_trigger('user_updated', $existinguser);
-
                 if ($bulk == UU_BULK_UPDATED or $bulk == UU_BULK_ALL) {
                     if (!in_array($user->id, $SESSION->bulk_users)) {
                         $SESSION->bulk_users[] = $user->id;
@@ -789,8 +787,7 @@ if ($formdata = $mform2->is_cancelled()) {
                 $upt->track('password', '-', 'normal', false);
             }
 
-            // create user - insert_record ignores any extra properties
-            $user->id = $DB->insert_record('user', $user);
+            $user->id = user_create_user($user, false);
             $upt->track('username', html_writer::link(new moodle_url('/user/profile.php', array('id'=>$user->id)), s($user->username)), 'normal', false);
 
             // pre-process custom profile menu fields data from csv file
@@ -812,8 +809,6 @@ if ($formdata = $mform2->is_cancelled()) {
             // make sure user context exists
             context_user::instance($user->id);
 
-            events_trigger('user_created', $user);
-
             if ($bulk == UU_BULK_NEW or $bulk == UU_BULK_ALL) {
                 if (!in_array($user->id, $SESSION->bulk_users)) {
                     $SESSION->bulk_users[] = $user->id;
index 0f66603..699babb 100644 (file)
@@ -4,6 +4,7 @@
     require_once($CFG->libdir.'/adminlib.php');
     require_once($CFG->libdir.'/authlib.php');
     require_once($CFG->dirroot.'/user/filters/lib.php');
+    require_once($CFG->dirroot.'/user/lib.php');
 
     $delete       = optional_param('delete', 0, PARAM_INT);
     $confirm      = optional_param('confirm', '', PARAM_ALPHANUM);   //md5 confirmation hash
         if ($user = $DB->get_record('user', array('id'=>$suspend, 'mnethostid'=>$CFG->mnet_localhost_id, 'deleted'=>0))) {
             if (!is_siteadmin($user) and $USER->id != $user->id and $user->suspended != 1) {
                 $user->suspended = 1;
-                $user->timemodified = time();
-                $DB->set_field('user', 'suspended', $user->suspended, array('id'=>$user->id));
-                $DB->set_field('user', 'timemodified', $user->timemodified, array('id'=>$user->id));
-                // force logout
+                // Force logout.
                 session_kill_user($user->id);
-                events_trigger('user_updated', $user);
+                user_update_user($user, false);
             }
         }
         redirect($returnurl);
         if ($user = $DB->get_record('user', array('id'=>$unsuspend, 'mnethostid'=>$CFG->mnet_localhost_id, 'deleted'=>0))) {
             if ($user->suspended != 0) {
                 $user->suspended = 0;
-                $user->timemodified = time();
-                $DB->set_field('user', 'suspended', $user->suspended, array('id'=>$user->id));
-                $DB->set_field('user', 'timemodified', $user->timemodified, array('id'=>$user->id));
-                events_trigger('user_updated', $user);
+                user_update_user($user, false);
             }
         }
         redirect($returnurl);
index de5061d..a01fc6e 100644 (file)
@@ -284,6 +284,7 @@ class auth_plugin_db extends auth_plugin_base {
             $remove_users = $DB->get_records_sql($sql, $params);
 
             if (!empty($remove_users)) {
+                require_once($CFG->dirroot.'/user/lib.php');
                 $trace->output(get_string('auth_dbuserstoremove','auth_db', count($remove_users)));
 
                 foreach ($remove_users as $user) {
@@ -294,8 +295,7 @@ class auth_plugin_db extends auth_plugin_base {
                         $updateuser = new stdClass();
                         $updateuser->id   = $user->id;
                         $updateuser->suspended = 1;
-                        $updateuser->timemodified = time();
-                        $DB->update_record('user', $updateuser);
+                        user_update_user($updateuser, false);
                         $trace->output(get_string('auth_dbsuspenduser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)), 1);
                     }
                 }
index e459004..a670cfc 100644 (file)
@@ -87,17 +87,15 @@ class auth_plugin_email extends auth_plugin_base {
     function user_signup($user, $notify=true) {
         global $CFG, $DB;
         require_once($CFG->dirroot.'/user/profile/lib.php');
+        require_once($CFG->dirroot.'/user/lib.php');
 
         $user->password = hash_internal_user_password($user->password);
 
-        $user->id = $DB->insert_record('user', $user);
+        $user->id = user_create_user($user, false);
 
-        /// Save any custom profile field information
+        // Save any custom profile field information.
         profile_save_data($user);
 
-        $user = $DB->get_record('user', array('id'=>$user->id));
-        events_trigger('user_created', $user);
-
         if (! send_confirmation_email($user)) {
             print_error('auth_emailnoemail','auth_email');
         }
index 866a838..1bad153 100644 (file)
@@ -78,6 +78,7 @@ if (!defined('LDAP_OPT_DIAGNOSTIC_MESSAGE')) {
 
 require_once($CFG->libdir.'/authlib.php');
 require_once($CFG->libdir.'/ldaplib.php');
+require_once($CFG->dirroot.'/user/lib.php');
 
 /**
  * LDAP authentication plugin.
@@ -550,7 +551,7 @@ class auth_plugin_ldap extends auth_plugin_base {
             print_error('auth_ldap_create_error', 'auth_ldap');
         }
 
-        $user->id = $DB->insert_record('user', $user);
+        $user->id = user_create_user($user, false);
 
         // Save any custom profile field information
         profile_save_data($user);
@@ -562,7 +563,6 @@ class auth_plugin_ldap extends auth_plugin_base {
         update_internal_user_password($user, $plainslashedpassword);
 
         $user = $DB->get_record('user', array('id'=>$user->id));
-        events_trigger('user_created', $user);
 
         if (! send_confirmation_email($user)) {
             print_error('noemail', 'auth_ldap');
@@ -612,12 +612,12 @@ class auth_plugin_ldap extends auth_plugin_base {
                 if (!$this->user_activate($username)) {
                     return AUTH_CONFIRM_FAIL;
                 }
-                $DB->set_field('user', 'confirmed', 1, array('id'=>$user->id));
+                $user->confirmed = 1;
                 if ($user->firstaccess == 0) {
-                    $DB->set_field('user', 'firstaccess', time(), array('id'=>$user->id));
+                    $user->firstaccess = time();
                 }
-                $euser = $DB->get_record('user', array('id' => $user->id));
-                events_trigger('user_updated', $euser);
+                require_once($CFG->dirroot.'/user/lib.php');
+                user_update_user($user, false);
                 return AUTH_CONFIRM_OK;
             }
         } else {
@@ -806,10 +806,8 @@ class auth_plugin_ldap extends auth_plugin_base {
                     $updateuser = new stdClass();
                     $updateuser->id = $user->id;
                     $updateuser->suspended = 1;
-                    $DB->update_record('user', $updateuser);
+                    user_update_user($updateuser, false);
                     echo "\t"; print_string('auth_dbsuspenduser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)); echo "\n";
-                    $euser = $DB->get_record('user', array('id' => $user->id));
-                    events_trigger('user_updated', $euser);
                     session_kill_user($user->id);
                 }
             } else {
@@ -835,10 +833,8 @@ class auth_plugin_ldap extends auth_plugin_base {
                     $updateuser->id = $user->id;
                     $updateuser->auth = $this->authtype;
                     $updateuser->suspended = 0;
-                    $DB->update_record('user', $updateuser);
+                    user_update_user($updateuser, false);
                     echo "\t"; print_string('auth_dbreviveduser', 'auth_db', array('name'=>$user->username, 'id'=>$user->id)); echo "\n";
-                    $euser = $DB->get_record('user', array('id' => $user->id));
-                    events_trigger('user_updated', $euser);
                 }
             } else {
                 print_string('nouserentriestorevive', 'auth_ldap');
@@ -950,10 +946,10 @@ class auth_plugin_ldap extends auth_plugin_base {
                     $user->lang = $CFG->lang;
                 }
 
-                $id = $DB->insert_record('user', $user);
+                $id = user_create_user($user, false);
                 echo "\t"; print_string('auth_dbinsertuser', 'auth_db', array('name'=>$user->username, 'id'=>$id)); echo "\n";
                 $euser = $DB->get_record('user', array('id' => $id));
-                events_trigger('user_created', $euser);
+
                 if (!empty($this->config->forcechangepassword)) {
                     set_user_preference('auth_forcepasswordchange', 1, $id);
                 }
@@ -1011,22 +1007,25 @@ class auth_plugin_ldap extends auth_plugin_base {
                 $updatekeys = array_keys($newinfo);
             }
 
-            foreach ($updatekeys as $key) {
-                if (isset($newinfo[$key])) {
-                    $value = $newinfo[$key];
-                } else {
-                    $value = '';
-                }
+            if (!empty($updatekeys)) {
+                $newuser = new stdClass();
+                $newuser->id = $userid;
+
+                foreach ($updatekeys as $key) {
+                    if (isset($newinfo[$key])) {
+                        $value = $newinfo[$key];
+                    } else {
+                        $value = '';
+                    }
 
-                if (!empty($this->config->{'field_updatelocal_' . $key})) {
-                    if ($user->{$key} != $value) { // only update if it's changed
-                        $DB->set_field('user', $key, $value, array('id'=>$userid));
+                    if (!empty($this->config->{'field_updatelocal_' . $key})) {
+                        // Only update if it's changed.
+                        if ($user->{$key} != $value) {
+                            $newuser->$key = $value;
+                        }
                     }
                 }
-            }
-            if (!empty($updatekeys)) {
-                $euser = $DB->get_record('user', array('id' => $userid));
-                events_trigger('user_updated', $euser);
+                user_update_user($newuser, false);
             }
         } else {
             return false;
index c1861fa..2f626bd 100644 (file)
@@ -216,6 +216,7 @@ class auth_plugin_mnet extends auth_plugin_base {
         global $CFG, $DB;
         require_once $CFG->dirroot . '/mnet/xmlrpc/client.php';
         require_once $CFG->libdir . '/gdlib.php';
+        require_once($CFG->dirroot.'/user/lib.php');
 
         // verify the remote host is configured locally before attempting RPC call
         if (! $remotehost = $DB->get_record('mnet_host', array('wwwroot' => $remotepeer->wwwroot, 'deleted' => 0))) {
@@ -361,8 +362,7 @@ class auth_plugin_mnet extends auth_plugin_base {
         if (empty($localuser->firstaccess)) { // Now firstaccess, grab it here
             $localuser->firstaccess = time();
         }
-
-        $DB->update_record('user', $localuser);
+        user_update_user($localuser, false);
 
         if (!$firsttime) {
             // repeat customer! let the IDP know about enrolments
index 6d7b054..39c2c4c 100644 (file)
@@ -72,7 +72,7 @@ class core_badges_observer {
     /**
      * Triggered when 'course_completed' event is triggered.
      *
-     * @param   \core\event\course_completed $event
+     * @param \core\event\course_completed $event
      */
     public static function course_criteria_review(\core\event\course_completed $event) {
         global $DB, $CFG;
@@ -105,4 +105,36 @@ class core_badges_observer {
             }
         }
     }
+
+    /**
+     * Triggered when 'user_updated' event happens.
+     *
+     * @param \core\event\user_updated $event event generated when user profile is updated.
+     */
+    public static function profile_criteria_review(\core\event\user_updated $event) {
+        global $DB, $CFG;
+
+        if (!empty($CFG->enablebadges)) {
+            require_once($CFG->dirroot.'/lib/badgeslib.php');
+            $userid = $event->objectid;
+
+            if ($rs = $DB->get_records('badge_criteria', array('criteriatype' => BADGE_CRITERIA_TYPE_PROFILE))) {
+                foreach ($rs as $r) {
+                    $badge = new badge($r->badgeid);
+                    if (!$badge->is_active() || $badge->is_issued($userid)) {
+                        continue;
+                    }
+
+                    if ($badge->criteria[BADGE_CRITERIA_TYPE_PROFILE]->review($userid)) {
+                        $badge->criteria[BADGE_CRITERIA_TYPE_PROFILE]->mark_complete($userid);
+
+                        if ($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->review($userid)) {
+                            $badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->mark_complete($userid);
+                            $badge->issue($userid);
+                        }
+                    }
+                }
+            }
+        }
+    }
 }
index 5436f01..e9c4ab3 100644 (file)
 require_once(dirname(dirname(__FILE__)) . '/config.php');
 require_once($CFG->libdir . '/badgeslib.php');
 
-$json = required_param('badge', PARAM_RAW);
+$json = optional_param('badge', null, PARAM_RAW);
+// Redirect to homepage if users are trying to access external badge through old url.
+if ($json) {
+    redirect($CFG->wwwroot, get_string('invalidrequest', 'error'), 3);
+}
+
+$hash = required_param('hash', PARAM_ALPHANUM);
+$userid = required_param('user', PARAM_INT);
+
+$PAGE->set_url(new moodle_url('/badges/external.php', array('hash' => $hash, 'user' => $userid)));
+
+// Using the same setting as user profile page.
+if (!empty($CFG->forceloginforprofiles)) {
+    require_login();
+    if (isguestuser()) {
+        $SESSION->wantsurl = $PAGE->url->out(false);
+        redirect(get_login_url());
+    }
+} else if (!empty($CFG->forcelogin)) {
+    require_login();
+}
+
+// Get all external badges of a user.
+$out = get_backpack_settings($userid);
+$badges = $out->badges;
+
+// Loop through the badges and check if supplied badge hash exists in user external badges.
+foreach ($badges as $b) {
+    if ($hash == hash("md5", $b->hostedUrl)) {
+        $badge = $b;
+        break;
+    }
+}
+
+// If we didn't find the badge, a user might be trying to replace userid parameter.
+if (is_null($badge)) {
+    print_error(get_string('error:externalbadgedoesntexist', 'badges'));
+}
 
 $PAGE->set_context(context_system::instance());
 $output = $PAGE->get_renderer('core', 'badges');
 
-$badge = new external_badge(unserialize($json));
+$badge = new external_badge($badge, $userid);
 
-$PAGE->set_url('/badges/external.php');
 $PAGE->set_pagelayout('base');
 $PAGE->set_title(get_string('issuedbadge', 'badges'));
 
index 1f52453..875d025 100644 (file)
@@ -53,11 +53,13 @@ $PAGE->set_heading($title);
 $PAGE->set_pagelayout('mydashboard');
 
 $backpack = $DB->get_record('badge_backpack', array('userid' => $USER->id));
+$badgescache = cache::make('core', 'externalbadges');
 
 if ($disconnect && $backpack) {
     require_sesskey();
     $DB->delete_records('badge_external', array('backpackid' => $backpack->id));
     $DB->delete_records('badge_backpack', array('userid' => $USER->id));
+    $badgescache->delete($USER->id);
     redirect(new moodle_url('/badges/mybackpack.php'));
 }
 
@@ -103,6 +105,7 @@ if ($backpack) {
                 $DB->insert_record('badge_external', $obj);
             }
         }
+        $badgescache->delete($USER->id);
         redirect(new moodle_url('/badges/mybadges.php'));
     }
 } else {
index 088b443..3075dc1 100644 (file)
@@ -81,9 +81,10 @@ class core_badges_renderer extends plugin_renderer_base {
                 $url = new moodle_url('badge.php', array('hash' => $badge->uniquehash));
             } else {
                 if (!$external) {
-                    $url = new moodle_url($CFG->wwwroot . '/badges/badge.php', array('hash' => $badge->uniquehash));
+                    $url = new moodle_url('/badges/badge.php', array('hash' => $badge->uniquehash));
                 } else {
-                    $url = new moodle_url($CFG->wwwroot . '/badges/external.php', array('badge' => serialize($badge)));
+                    $hash = hash('md5', $badge->hostedUrl);
+                    $url = new moodle_url('/badges/external.php', array('hash' => $hash, 'user' => $userid));
                 }
             }
             $actions = html_writer::tag('div', $push . $download . $status, array('class' => 'badge-actions'));
@@ -276,6 +277,7 @@ class core_badges_renderer extends plugin_renderer_base {
     protected function render_issued_badge(issued_badge $ibadge) {
         global $USER, $CFG, $DB;
         $issued = $ibadge->issued;
+        $userinfo = $ibadge->recipient;
         $badge = new badge($ibadge->badgeid);
         $today_date = date('Y-m-d');
         $today = strtotime($today_date);
@@ -286,7 +288,7 @@ class core_badges_renderer extends plugin_renderer_base {
         $imagetable = new html_table();
         $imagetable->attributes = array('class' => 'clearfix badgeissuedimage');
         $imagetable->data[] = array(html_writer::empty_tag('img', array('src' => $issued['badge']['image'])));
-        if ($USER->id == $ibadge->recipient && !empty($CFG->enablebadges)) {
+        if ($USER->id == $userinfo->id && !empty($CFG->enablebadges)) {
             $imagetable->data[] = array($this->output->single_button(
                         new moodle_url('/badges/badge.php', array('hash' => $ibadge->hash, 'bake' => true)),
                         get_string('download'),
@@ -307,11 +309,20 @@ class core_badges_renderer extends plugin_renderer_base {
         $datatable = new html_table();
         $datatable->attributes = array('class' => 'badgeissuedinfo');
         $datatable->colclasses = array('bfield', 'bvalue');
+
+        // Recipient information.
+        $datatable->data[] = array($this->output->heading(get_string('recipientdetails', 'badges'), 3), '');
+        $datatable->data[] = array(get_string('name'), fullname($userinfo));
+        if (empty($userinfo->backpackemail)) {
+            $datatable->data[] = array(get_string('email'), obfuscate_mailto($userinfo->accountemail));
+        } else {
+            $datatable->data[] = array(get_string('email'), obfuscate_mailto($userinfo->backpackemail));
+        }
+
         $datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), '');
         $datatable->data[] = array(get_string('issuername', 'badges'), $badge->issuername);
         if (isset($badge->issuercontact) && !empty($badge->issuercontact)) {
-            $datatable->data[] = array(get_string('contact', 'badges'),
-                html_writer::tag('a', $badge->issuercontact, array('href' => 'mailto:' . $badge->issuercontact)));
+            $datatable->data[] = array(get_string('contact', 'badges'), obfuscate_mailto($badge->issuercontact));
         }
         $datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), '');
         $datatable->data[] = array(get_string('name'), $badge->name);
@@ -347,7 +358,7 @@ class core_badges_renderer extends plugin_renderer_base {
 
         // Print evidence.
         $agg = $badge->get_aggregation_methods();
-        $evidence = $badge->get_criteria_completions($ibadge->recipient);
+        $evidence = $badge->get_criteria_completions($userinfo->id);
         $eids = array_map(create_function('$o', 'return $o->critid;'), $evidence);
         unset($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]);
 
@@ -378,6 +389,7 @@ class core_badges_renderer extends plugin_renderer_base {
         $issued = $ibadge->issued;
         $assertion = $issued->assertion;
         $issuer = $assertion->badge->issuer;
+        $userinfo = $ibadge->recipient;
         $table = new html_table();
 
         $imagetable = new html_table();
@@ -387,13 +399,29 @@ class core_badges_renderer extends plugin_renderer_base {
         $datatable = new html_table();
         $datatable->attributes = array('class' => 'badgeissuedinfo');
         $datatable->colclasses = array('bfield', 'bvalue');
+
+        // Recipient information.
+        $datatable->data[] = array($this->output->heading(get_string('recipientdetails', 'badges'), 3), '');
+        // Technically, we should alway have a user at this point, but added an extra check just in case.
+        if ($userinfo) {
+            $datatable->data[] = array(get_string('name'), fullname($userinfo));
+            if (!$ibadge->valid) {
+                $notify = $this->output->notification(get_string('recipientvalidationproblem', 'badges'), 'notifynotice');
+                $datatable->data[] = array(get_string('email'), obfuscate_mailto($userinfo->email) . $notify);
+            } else {
+                $datatable->data[] = array(get_string('email'), obfuscate_mailto($userinfo->email));
+            }
+        } else {
+            $notify = $this->output->notification(get_string('recipientidentificationproblem', 'badges'), 'notifynotice');
+            $datatable->data[] = array(get_string('name'), $notify);
+        }
+
         $datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), '');
         $datatable->data[] = array(get_string('issuername', 'badges'), $issuer->name);
         $datatable->data[] = array(get_string('issuerurl', 'badges'),
                 html_writer::tag('a', $issuer->origin, array('href' => $issuer->origin)));
         if (isset($issuer->contact)) {
-            $datatable->data[] = array(get_string('contact', 'badges'),
-                html_writer::tag('a', $issuer->contact, array('href' => 'mailto:' . $issuer->contact)));
+            $datatable->data[] = array(get_string('contact', 'badges'), obfuscate_mailto($issuer->contact));
         }
         $datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), '');
         $datatable->data[] = array(get_string('name'), $assertion->badge->name);
@@ -875,7 +903,7 @@ class issued_badge implements renderable {
     public $issued;
 
     /** @var badge recipient */
-    public $recipient = 0;
+    public $recipient;
 
     /** @var badge visibility to others */
     public $visible = 0;
@@ -901,7 +929,12 @@ class issued_badge implements renderable {
                 WHERE ' . $DB->sql_compare_text('uniquehash', 40) . ' = ' . $DB->sql_compare_text(':hash', 40),
                 array('hash' => $hash), IGNORE_MISSING);
         if ($rec) {
-            $this->recipient = $rec->userid;
+            // Get a recipient from database.
+            $user = $DB->get_record_sql('SELECT u.id, u.lastname, u.firstname,
+                                                u.email AS accountemail, b.email AS backpackemail
+                        FROM {user} u LEFT JOIN {badge_backpack} b ON u.id = b.userid
+                        WHERE u.id = :userid', array('userid' => $rec->userid));
+            $this->recipient = $user;
             $this->visible = $rec->visible;
             $this->badgeid = $rec->badgeid;
         }
@@ -915,13 +948,51 @@ class external_badge implements renderable {
     /** @var issued badge */
     public $issued;
 
+    /** @var User ID */
+    public $recipient;
+
+    /** @var validation of external badge */
+    public $valid = true;
+
     /**
      * Initializes the badge to display
      *
-     * @param string $json External badge information.
+     * @param object $badge External badge information.
+     * @param int $recipient User id.
      */
-    public function __construct($json) {
-        $this->issued = $json;
+    public function __construct($badge, $recipient) {
+        global $DB;
+        // At this point a user has connected a backpack. So, we are going to get
+        // their backpack email rather than their account email.
+        $user = $DB->get_record_sql('SELECT u.lastname, u.firstname, b.email
+                    FROM {user} u INNER JOIN {badge_backpack} b ON u.id = b.userid
+                    WHERE userid = :userid', array('userid' => $recipient), IGNORE_MISSING);
+
+        $this->issued = $badge;
+        $this->recipient = $user;
+
+        // Check if recipient is valid.
+        // There is no way to be 100% sure that a badge belongs to a user.
+        // Backpack does not return any recipient information.
+        // All we can do is compare that backpack email hashed using salt
+        // provided in the assertion matches a badge recipient from the assertion.
+        if ($user) {
+            if (validate_email($badge->assertion->recipient) && $badge->assertion->recipient == $user->email) {
+                // If we have email, compare emails.
+                $this->valid = true;
+            } else if ($badge->assertion->recipient == 'sha256$' . hash('sha256', $user->email)) {
+                // If recipient is hashed, but no salt, compare hashes without salt.
+                $this->valid = true;
+            } else if ($badge->assertion->recipient == 'sha256$' . hash('sha256', $user->email . $badge->assertion->salt)) {
+                // If recipient is hashed, compare hashes.
+                $this->valid = true;
+            } else {
+                // Otherwise, we cannot be sure that this user is a recipient.
+                $this->valid = false;
+            }
+        } else {
+            $this->valid = false;
+        }
     }
 }
 
@@ -1016,7 +1087,7 @@ class badge_user_collection extends badge_collection implements renderable {
         parent::__construct($badges);
 
         if (!empty($CFG->badges_allowexternalbackpack)) {
-            $this->backpack = get_backpack_settings($userid);
+            $this->backpack = get_backpack_settings($userid, true);
         }
     }
 }
index fa7b7cb..a3b2878 100644 (file)
@@ -260,4 +260,23 @@ class core_badgeslib_testcase extends advanced_testcase {
         $this->assertDebuggingCalled('Error baking badge image!');
         $this->assertTrue($badge->is_issued($this->user->id));
     }
+
+    /**
+     * Test badges observer when user_updated event is fired.
+     */
+    public function test_badges_observer_profile_criteria_review() {
+        $badge = new badge($this->coursebadge);
+        $this->assertFalse($badge->is_issued($this->user->id));
+
+        $criteria_overall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id));
+        $criteria_overall->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ANY));
+        $criteria_overall1 = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_PROFILE, 'badgeid' => $badge->id));
+        $criteria_overall1->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ALL, 'field_address' => 'address'));
+
+        $this->user->address = 'Test address';
+        user_update_user($this->user, false);
+        // Check if badge is awarded.
+        $this->assertDebuggingCalled('Error baking badge image!');
+        $this->assertTrue($badge->is_issued($this->user->id));
+    }
 }
index f6ec711..4d85032 100644 (file)
@@ -53,6 +53,7 @@ $string['course_summary_key'] = 'Summary';
 $string['createcourseextid'] = 'CREATE User enrolled to a nonexistant course \'{$a->courseextid}\'';
 $string['createnotcourseextid'] = 'User enrolled to a nonexistant course \'{$a->courseextid}\'';
 $string['creatingcourse'] =  'Creating course \'{$a}\'...';
+$string['duplicateshortname'] = "Course creation failed. Duplicate short name. Skipping course with idnumber '{\$a->idnumber}'...";
 $string['editlock'] = 'Lock value';
 $string['emptyenrolment'] = "Empty enrolment for role '{\$a->role_shortname}' in course '{\$a->course_shortname}'\n";
 $string['enrolname'] = 'LDAP';
index 9ebacb8..73eb118 100644 (file)
@@ -990,6 +990,12 @@ class enrol_ldap_plugin extends enrol_plugin {
             $course->summary = $course_ext[$this->get_config('course_summary')][0];
         }
 
+        // Check if the shortname already exists if it does - skip course creation.
+        if ($DB->record_exists('course', array('shortname' => $course->shortname))) {
+            $trace->output(get_string('duplicateshortname', 'enrol_ldap', $course));
+            return false;
+        }
+
         $newcourse = create_course($course);
         return $newcourse->id;
     }
index 5c3e345..a4f7a00 100644 (file)
@@ -257,7 +257,17 @@ class enrol_manual_editselectedusers_operation extends enrol_bulk_enrolment_oper
                 foreach ($user->enrolments as $enrolment) {
                     $enrolment->courseid  = $enrolment->enrolmentinstance->courseid;
                     $enrolment->enrol     = 'manual';
-                    events_trigger('user_enrol_modified', $enrolment);
+                    // Trigger event.
+                    $event = \core\event\user_enrolment_updated::create(
+                            array(
+                                'objectid' => $enrolment->id,
+                                'courseid' => $enrolment->courseid,
+                                'context' => context_course::instance($enrolment->courseid),
+                                'relateduserid' => $user->id,
+                                'other' => array('enrol' => 'manual')
+                                )
+                            );
+                    $event->trigger();
                 }
             }
             return true;
diff --git a/enrol/meta/classes/observer.php b/enrol/meta/classes/observer.php
new file mode 100644 (file)
index 0000000..625d232
--- /dev/null
@@ -0,0 +1,102 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Event observer for meta enrolment plugin.
+ *
+ * @package    enrol_meta
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->dirroot.'/enrol/meta/locallib.php');
+
+/**
+ * Event observer for enrol_meta.
+ *
+ * @package    enrol_meta
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class enrol_meta_observer extends enrol_meta_handler {
+
+    /**
+     * Triggered via user_enrolment_created event.
+     *
+     * @param \core\event\user_enrolment_created $event
+     * @return bool true on success.
+     */
+    public static function user_enrolment_created(\core\event\user_enrolment_created $event) {
+        if (!enrol_is_enabled('meta')) {
+            // No more enrolments for disabled plugins.
+            return true;
+        }
+
+        if ($event->other['enrol'] === 'meta') {
+            // Prevent circular dependencies - we can not sync meta enrolments recursively.
+            return true;
+        }
+
+        self::sync_course_instances($event->courseid, $event->relateduserid);
+        return true;
+    }
+
+    /**
+     * Triggered via user_enrolment_deleted event.
+     *
+     * @param \core\event\user_enrolment_deleted $event
+     * @return bool true on success.
+     */
+    public static function user_enrolment_deleted(\core\event\user_enrolment_deleted $event) {
+        if (!enrol_is_enabled('meta')) {
+            // This is slow, let enrol_meta_sync() deal with disabled plugin.
+            return true;
+        }
+
+        if ($event->other['enrol'] === 'meta') {
+            // Prevent circular dependencies - we can not sync meta enrolments recursively.
+            return true;
+        }
+
+        self::sync_course_instances($event->courseid, $event->relateduserid);
+
+        return true;
+    }
+
+    /**
+     * Triggered via user_enrolment_updated event.
+     *
+     * @param \core\event\user_enrolment_updated $event
+     * @return bool true on success
+     */
+    public static function user_enrolment_updated(\core\event\user_enrolment_updated $event) {
+        if (!enrol_is_enabled('meta')) {
+            // No modifications if plugin disabled.
+            return true;
+        }
+
+        if ($event->other['enrol'] === 'meta') {
+            // Prevent circular dependencies - we can not sync meta enrolments recursively.
+            return true;
+        }
+
+        self::sync_course_instances($event->courseid, $event->relateduserid);
+
+        return true;
+    }
+}
index c1a2d70..08c9625 100644 (file)
@@ -41,31 +41,27 @@ $handlers = array (
         'internal'         => 1,
     ),
 
-    'user_enrolled' => array (
+    'course_deleted' => array (
         'handlerfile'      => '/enrol/meta/locallib.php',
-        'handlerfunction'  => array('enrol_meta_handler', 'user_enrolled'),
+        'handlerfunction'  => array('enrol_meta_handler', 'course_deleted'),
         'schedule'         => 'instant',
         'internal'         => 1,
     ),
+);
 
-    'user_unenrolled' => array (
-        'handlerfile'      => '/enrol/meta/locallib.php',
-        'handlerfunction'  => array('enrol_meta_handler', 'user_unenrolled'),
-        'schedule'         => 'instant',
-        'internal'         => 1,
-    ),
+// List of observers.
+$observers = array(
 
-    'user_enrol_modified' => array (
-        'handlerfile'      => '/enrol/meta/locallib.php',
-        'handlerfunction'  => array('enrol_meta_handler', 'user_enrol_modified'),
-        'schedule'         => 'instant',
-        'internal'         => 1,
+    array(
+        'eventname'   => '\core\event\user_enrolment_created',
+        'callback'    => 'enrol_meta_observer::user_enrolment_created',
     ),
-
-    'course_deleted' => array (
-        'handlerfile'      => '/enrol/meta/locallib.php',
-        'handlerfunction'  => array('enrol_meta_handler', 'course_deleted'),
-        'schedule'         => 'instant',
-        'internal'         => 1,
+    array(
+        'eventname'   => '\core\event\user_enrolment_deleted',
+        'callback'    => 'enrol_meta_observer::user_enrolment_deleted',
+    ),
+    array(
+        'eventname'   => '\core\event\user_enrolment_updated',
+        'callback'    => 'enrol_meta_observer::user_enrolment_updated',
     ),
 );
index 3a3c26b..c20bfaf 100644 (file)
@@ -293,72 +293,6 @@ class enrol_meta_handler {
         return true;
     }
 
-    /**
-     * Triggered via user enrolled event.
-     * @static
-     * @param stdClass $ue
-     * @return bool success
-     */
-    public static function user_enrolled($ue) {
-        if (!enrol_is_enabled('meta')) {
-            // no more enrolments for disabled plugins
-            return true;
-        }
-
-        if ($ue->enrol === 'meta') {
-            // prevent circular dependencies - we can not sync meta enrolments recursively
-            return true;
-        }
-
-        self::sync_course_instances($ue->courseid, $ue->userid);
-
-        return true;
-    }
-
-    /**
-     * Triggered via user unenrolled event.
-     * @static
-     * @param stdClass $ue
-     * @return bool success
-     */
-    public static function user_unenrolled($ue) {
-        if (!enrol_is_enabled('meta')) {
-            // This is slow, let enrol_meta_sync() deal with disabled plugin.
-            return true;
-        }
-
-        if ($ue->enrol === 'meta') {
-            // prevent circular dependencies - we can not sync meta enrolments recursively
-            return true;
-        }
-
-        self::sync_course_instances($ue->courseid, $ue->userid);
-
-        return true;
-    }
-
-    /**
-     * Triggered via user enrolment modification  event.
-     * @static
-     * @param stdClass $ue
-     * @return bool success
-     */
-    public static function user_enrol_modified($ue) {
-        if (!enrol_is_enabled('meta')) {
-            // no modifications if plugin disabled
-            return true;
-        }
-
-        if ($ue->enrol === 'meta') {
-            // prevent circular dependencies - we can not sync meta enrolments recursively
-            return true;
-        }
-
-        self::sync_course_instances($ue->courseid, $ue->userid);
-
-        return true;
-    }
-
     /**
      * Triggered via course_deleted event.
      * @static
index fdfec33..05cb522 100644 (file)
@@ -439,4 +439,112 @@ class enrol_meta_plugin_testcase extends advanced_testcase {
         delete_course($course4, false);
 
     }
+
+    /**
+     * Test user_enrolment_created event.
+     */
+    public function test_user_enrolment_created_observer() {
+        global $DB;
+
+        $this->resetAfterTest();
+
+        $metaplugin = enrol_get_plugin('meta');
+        $user1 = $this->getDataGenerator()->create_user();
+        $course1 = $this->getDataGenerator()->create_course();
+        $course2 = $this->getDataGenerator()->create_course();
+        $student = $DB->get_record('role', array('shortname' => 'student'));
+
+        $e1 = $metaplugin->add_instance($course2, array('customint1' => $course1->id));
+        $enrol1 = $DB->get_record('enrol', array('id' => $e1));
+
+        // Enrol user and capture event.
+        $sink = $this->redirectEvents();
+
+        $metaplugin->enrol_user($enrol1, $user1->id, $student->id);
+        $events = $sink->get_events();
+        $sink->close();
+        $event = array_shift($events);
+
+        // Test Event.
+        $dbuserenrolled = $DB->get_record('user_enrolments', array('userid' => $user1->id));
+        $this->assertInstanceOf('\core\event\user_enrolment_created', $event);
+        $this->assertEquals($dbuserenrolled->id, $event->objectid);
+        $this->assertEquals('user_enrolled', $event->get_legacy_eventname());
+        $expectedlegacyeventdata = $dbuserenrolled;
+        $expectedlegacyeventdata->enrol = 'meta';
+        $expectedlegacyeventdata->courseid = $course2->id;
+        $this->assertEventLegacyData($expectedlegacyeventdata, $event);
+    }
+
+    /**
+     * Test user_enrolment_deleted observer.
+     */
+    public function test_user_enrolment_deleted_observer() {
+        global $DB;
+
+        $this->resetAfterTest(true);
+
+        $metalplugin = enrol_get_plugin('meta');
+        $user1 = $this->getDataGenerator()->create_user();
+        $course1 = $this->getDataGenerator()->create_course();
+        $course2 = $this->getDataGenerator()->create_course();
+        $student = $DB->get_record('role', array('shortname'=>'student'));
+
+        $e1 = $metalplugin->add_instance($course2, array('customint1' => $course1->id));
+        $enrol1 = $DB->get_record('enrol', array('id' => $e1));
+
+        // Enrol user.
+        $metalplugin->enrol_user($enrol1, $user1->id, $student->id);
+        $this->assertEquals(1, $DB->count_records('user_enrolments'));
+
+        // Unenrol user and capture event.
+        $sink = $this->redirectEvents();
+        $metalplugin->unenrol_user($enrol1, $user1->id);
+        $events = $sink->get_events();
+        $sink->close();
+        $event = array_pop($events);
+
+        $this->assertEquals(0, $DB->count_records('user_enrolments'));
+        $this->assertInstanceOf('\core\event\user_enrolment_deleted', $event);
+        $this->assertEquals('user_unenrolled', $event->get_legacy_eventname());
+    }
+
+    /**
+     * Test user_enrolment_updated event.
+     */
+    public function test_user_enrolment_updated_observer() {
+        global $DB;
+
+        $this->resetAfterTest(true);
+
+        $metalplugin = enrol_get_plugin('meta');
+        $user1 = $this->getDataGenerator()->create_user();
+        $course1 = $this->getDataGenerator()->create_course();
+        $course2 = $this->getDataGenerator()->create_course();
+        $student = $DB->get_record('role', array('shortname'=>'student'));
+
+        $e1 = $metalplugin->add_instance($course2, array('customint1' => $course1->id));
+        $enrol1 = $DB->get_record('enrol', array('id' => $e1));
+
+        // Enrol user.
+        $metalplugin->enrol_user($enrol1, $user1->id, $student->id);
+        $this->assertEquals(1, $DB->count_records('user_enrolments'));
+
+        // Updated enrolment for user and capture event.
+        $sink = $this->redirectEvents();
+        $metalplugin->update_user_enrol($enrol1, $user1->id, ENROL_USER_SUSPENDED, null, time());
+        $events = $sink->get_events();
+        $sink->close();
+        $event = array_shift($events);
+
+        // Test Event.
+        $dbuserenrolled = $DB->get_record('user_enrolments', array('userid' => $user1->id));
+        $this->assertInstanceOf('\core\event\user_enrolment_updated', $event);
+        $this->assertEquals($dbuserenrolled->id, $event->objectid);
+        $this->assertEquals('user_enrol_modified', $event->get_legacy_eventname());
+        $expectedlegacyeventdata = $dbuserenrolled;
+        $expectedlegacyeventdata->enrol = 'meta';
+        $expectedlegacyeventdata->courseid = $course2->id;
+        $this->assertEventLegacyData($expectedlegacyeventdata, $event);
+    }
 }
index cba40a8..bbdc3bc 100644 (file)
@@ -279,4 +279,41 @@ class core_enrollib_testcase extends advanced_testcase {
         // It should be course 1.
         $this->assertEquals($sharedcourse->id, $course1->id);
     }
+
+    /**
+     * Test user enrolment created event.
+     */
+    public function test_user_enrolment_created_event() {
+        global $DB;
+
+        $this->resetAfterTest();
+
+        $studentrole = $DB->get_record('role', array('shortname'=>'student'));
+        $this->assertNotEmpty($studentrole);
+
+        $admin = get_admin();
+
+        $course1 = $this->getDataGenerator()->create_course();
+
+        $maninstance1 = $DB->get_record('enrol', array('courseid'=>$course1->id, 'enrol'=>'manual'), '*', MUST_EXIST);
+
+        $manual = enrol_get_plugin('manual');
+        $this->assertNotEmpty($manual);
+
+        // Enrol user and capture event.
+        $sink = $this->redirectEvents();
+        $manual->enrol_user($maninstance1, $admin->id, $studentrole->id);
+        $events = $sink->get_events();
+        $sink->close();
+        $event = array_shift($events);
+
+        $dbuserenrolled = $DB->get_record('user_enrolments', array('userid' => $admin->id));
+        $this->assertInstanceOf('\core\event\user_enrolment_created', $event);
+        $this->assertEquals($dbuserenrolled->id, $event->objectid);
+        $this->assertEquals('user_enrolled', $event->get_legacy_eventname());
+        $expectedlegacyeventdata = $dbuserenrolled;
+        $expectedlegacyeventdata->enrol = $manual->get_name();
+        $expectedlegacyeventdata->courseid = $course1->id;
+        $this->assertEventLegacyData($expectedlegacyeventdata, $event);
+    }
 }
index 199d1eb..8ccb757 100644 (file)
@@ -201,9 +201,9 @@ class core_files_renderer extends plugin_renderer_base {
     <div class="fp-navbar">
         <div class="filemanager-toolbar">
             <div class="fp-toolbar">
-                <div class="{!}fp-btn-add"><a href="#"><img src="'.$this->pix_url('a/add_file').'" /> '.$straddfile.'</a></div>
-                <div class="{!}fp-btn-mkdir"><a href="#"><img src="'.$this->pix_url('a/create_folder').'" /> '.$strmakedir.'</a></div>
-                <div class="{!}fp-btn-download"><a href="#"><img src="'.$this->pix_url('a/download_all').'" /> '.$strdownload.'</a></div>
+                <div class="{!}fp-btn-add"><a role="button" href="#"><img src="'.$this->pix_url('a/add_file').'" /> '.$straddfile.'</a></div>
+                <div class="{!}fp-btn-mkdir"><a role="button" href="#"><img src="'.$this->pix_url('a/create_folder').'" /> '.$strmakedir.'</a></div>
+                <div class="{!}fp-btn-download"><a role="button" href="#"><img src="'.$this->pix_url('a/download_all').'" /> '.$strdownload.'</a></div>
             </div>
             <div class="{!}fp-viewbar">
                 <a title="'. get_string('displayicons', 'repository') .'" class="{!}fp-vb-icons" href="#"></a>
@@ -521,10 +521,10 @@ class core_files_renderer extends plugin_renderer_base {
      */
     private function fp_js_template_generallayout() {
         $rv = '
-<div class="file-picker fp-generallayout">
+<div tabindex="0" class="file-picker fp-generallayout" role="dialog" aria-live="assertive">
     <div class="fp-repo-area">
         <ul class="fp-list">
-            <li class="{!}fp-repo"><a href="#"><img class="{!}fp-repo-icon" alt="'. get_string('repositoryicon', 'repository') .'" width="16" height="16" />&nbsp;<span class="{!}fp-repo-name"></span></a></li>
+            <li class="{!}fp-repo"><a href="#"><img class="{!}fp-repo-icon" alt=" " width="16" height="16" />&nbsp;<span class="{!}fp-repo-name"></span></a></li>
         </ul>
     </div>
     <div class="fp-repo-items" tabindex="0">
index b7fa140..9bd6f21 100644 (file)
@@ -189,7 +189,7 @@ abstract class grade_export {
             $name .= ' ('.get_string('feedback').')';
         }
 
-        return strip_tags($name);
+        return html_to_text($name, 0, false);
     }
 
     /**
index 9e5b147..09cc675 100644 (file)
@@ -101,7 +101,9 @@ $string['badgeprivacysetting_help'] = 'Badges you earn can be displayed on your
 You can still control individual badge privacy settings on your "My badges" page.';
 $string['badgeprivacysetting_str'] = 'Automatically show badges I earn on my profile page';
 $string['badgesalt'] = 'Salt for hashing the recepient\'s email address';
-$string['badgesalt_desc'] = 'Using a hash allows backpack services to confirm the badge earner without having to expose their email address. This setting should only use numbers and letters.';
+$string['badgesalt_desc'] = 'Using a hash allows backpack services to confirm the badge earner without having to expose their email address. This setting should only use numbers and letters.
+
+Note: For recipient verification purposes, please avoid changing this setting once you start issuing badges.';
 $string['badgesdisabled'] = 'Badges are not enabled on this site.';
 $string['badgesearned'] = 'Number of badges earned: {$a}';
 $string['badgesettings'] = 'Badges settings';
@@ -203,6 +205,7 @@ $string['error:cannotact'] = 'Cannot activate the badge. ';
 $string['error:cannotawardbadge'] = 'Cannot award badge to a user.';
 $string['error:clone'] = 'Cannot clone the badge.';
 $string['error:duplicatename'] = 'Badge with such name already exists in the system.';
+$string['error:externalbadgedoesntexist'] = 'Badge not found';
 $string['error:invalidbadgeurl'] = 'Invalid badge issuer URL format.';
 $string['error:invalidcriteriatype'] = 'Invalid criteria type.';
 $string['error:invalidexpiredate'] = 'Expiry date has to be in the future.';
@@ -305,6 +308,9 @@ $string['numawardstat'] = 'This badge has been issued {$a} user(s).';
 $string['overallcrit'] = 'of the selected criteria are complete.';
 $string['potentialrecipients'] = 'Potential badge recipients';
 $string['recipients'] = 'Badge recipients';
+$string['recipientdetails'] = 'Recipient details';
+$string['recipientidentificationproblem'] = 'Cannot find a recipient of this badge among the existing users.';
+$string['recipientvalidationproblem'] = 'Current user cannot be verified as a recipient of this badge.';
 $string['relative'] = 'Relative date';
 $string['requiredcourse'] = 'At least one course should be added to the courseset criterion.';
 $string['reviewbadge'] = 'Review badge criteria';
index a60b503..47403f2 100644 (file)
@@ -44,6 +44,7 @@ $string['cachedef_coursecontacts'] = 'List of course contacts';
 $string['cachedef_coursecattree'] = 'Course categories tree';
 $string['cachedef_databasemeta'] = 'Database meta information';
 $string['cachedef_eventinvalidation'] = 'Event invalidation';
+$string['cachedef_externalbadges'] = 'External badges for particular user';
 $string['cachedef_groupdata'] = 'Course group information';
 $string['cachedef_htmlpurifier'] = 'HTML Purifier - cleaned content';
 $string['cachedef_langmenu'] = 'List of available languages';
index 2beaab1..50c6573 100644 (file)
@@ -69,6 +69,9 @@ $string['errorenrolcohort'] = 'Error creating cohort sync enrolment instance in
 $string['errorenrolcohortusers'] = 'Error enrolling cohort members in this course.';
 $string['errorthresholdlow'] = 'Notification threshold must be at least 1 day.';
 $string['errorwithbulkoperation'] = 'There was an error while processing your bulk enrolment change.';
+$string['eventuserenrolmentcreated'] = 'User enrolled in course';
+$string['eventuserenrolmentdeleted'] = 'User unenrolled from course';
+$string['eventuserenrolmentupdated'] = 'User unenrolment updated';
 $string['expirynotify'] = 'Notify before enrolment expires';
 $string['expirynotify_help'] = 'This setting determines whether enrolment expiry notification messages are sent.';
 $string['expirynotifyall'] = 'Enroller and enrolled user';
index 10c69f5..ac711e3 100644 (file)
@@ -667,6 +667,10 @@ $string['eventcoursedeleted'] = 'Course deleted';
 $string['eventcourserestored'] = 'Course restored';
 $string['eventcourseupdated'] = 'Course updated';
 $string['eventcoursesectionupdated'] = ' Course section updated';
+$string['eventusercreated'] = 'User created';
+$string['eventuserdeleted'] = 'User deleted';
+$string['eventuserloggedout'] = 'User logged out';
+$string['eventuserupdated'] = 'User updated';
 $string['everybody'] = 'Everybody';
 $string['executeat'] = 'Execute at';
 $string['existing'] = 'Existing';
index 4901456..061ecd3 100644 (file)
@@ -931,40 +931,6 @@ function badges_add_course_navigation(navigation_node $coursenode, stdClass $cou
     }
 }
 
-/**
- * Triggered when 'user_updated' event happens.
- *
- * @param   object $eventdata Holds all information about a user.
- * @return  boolean
- */
-function badges_award_handle_profile_criteria_review(stdClass $eventdata) {
-    global $DB, $CFG;
-
-    if (!empty($CFG->enablebadges)) {
-        $userid = $eventdata->id;
-
-        if ($rs = $DB->get_records('badge_criteria', array('criteriatype' => BADGE_CRITERIA_TYPE_PROFILE))) {
-            foreach ($rs as $r) {
-                $badge = new badge($r->badgeid);
-                if (!$badge->is_active() || $badge->is_issued($userid)) {
-                    continue;
-                }
-
-                if ($badge->criteria[BADGE_CRITERIA_TYPE_PROFILE]->review($userid)) {
-                    $badge->criteria[BADGE_CRITERIA_TYPE_PROFILE]->mark_complete($userid);
-
-                    if ($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->review($userid)) {
-                        $badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->mark_complete($userid);
-                        $badge->issue($userid);
-                    }
-                }
-            }
-        }
-    }
-
-    return true;
-}
-
 /**
  * Triggered when badge is manually awarded.
  *
@@ -1086,13 +1052,25 @@ function badges_bake($hash, $badgeid, $userid = 0, $pathhash = false) {
 /**
  * Returns external backpack settings and badges from this backpack.
  *
+ * This function first checks if badges for the user are cached and
+ * tries to retrieve them from the cache. Otherwise, badges are obtained
+ * through curl request to the backpack.
+ *
  * @param int $userid Backpack user ID.
+ * @param boolean $refresh Refresh badges collection in cache.
  * @return null|object Returns null is there is no backpack or object with backpack settings.
  */
-function get_backpack_settings($userid) {
+function get_backpack_settings($userid, $refresh = false) {
     global $DB;
     require_once(dirname(dirname(__FILE__)) . '/badges/lib/backpacklib.php');
 
+    // Try to get badges from cache first.
+    $badgescache = cache::make('core', 'externalbadges');
+    $out = $badgescache->get($userid);
+    if ($out !== false && !$refresh) {
+        return $out;
+    }
+    // Get badges through curl request to the backpack.
     $record = $DB->get_record('badge_backpack', array('userid' => $userid));
     if ($record) {
         $backpack = new OpenBadgesBackpackHandler($record);
@@ -1117,6 +1095,7 @@ function get_backpack_settings($userid) {
             $out->totalcollections = 0;
         }
 
+        $badgescache->set($userid, $out);
         return $out;
     }
 
index 2ac98dd..64727eb 100644 (file)
@@ -58,8 +58,8 @@ class behat_util extends testing_util {
      * @return void
      */
     public static function install_site() {
-        global $DB;
-
+        global $DB, $CFG;
+        require_once($CFG->dirroot.'/user/lib.php');
         if (!defined('BEHAT_UTIL')) {
             throw new coding_exception('This method can be only used by Behat CLI tool');
         }
@@ -82,7 +82,7 @@ class behat_util extends testing_util {
         $user->lastname = 'User';
         $user->city = 'Perth';
         $user->country = 'AU';
-        $DB->update_record('user', $user);
+        user_update_user($user, false);
 
         // Disable email message processor.
         $DB->set_field('message_processors', 'enabled', '0', array('name' => 'email'));
index f14b892..9738cd9 100644 (file)
@@ -998,7 +998,7 @@ class block_manager {
      *
      * @param string $region The name of the region to check
      */
-    protected function ensure_content_created($region, $output) {
+    public function ensure_content_created($region, $output) {
         $this->ensure_instances_exist($region);
         if (!array_key_exists($region, $this->visibleblockcontent)) {
             $contents = array();
diff --git a/lib/classes/event/user_created.php b/lib/classes/event/user_created.php
new file mode 100644 (file)
index 0000000..892efd5
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * User created event.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace core\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Event when new user profile is created.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class user_created extends base {
+
+    /**
+     * Initialise required event data properties.
+     */
+    protected function init() {
+        $this->data['objecttable'] = 'user';
+        $this->data['crud'] = 'c';
+        $this->data['level'] = self::LEVEL_OTHER;
+    }
+
+    /**
+     * Returns localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('eventusercreated');
+    }
+
+    /**
+     * Returns non-localised event description with id's for admin use only.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return 'Profile created for user '.$this->objectid;
+    }
+
+    /**
+     * Returns relevant URL.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/user/view.php', array('id' => $this->objectid));
+    }
+
+    /**
+     * Return name of the legacy event, which is replaced by this event.
+     *
+     * @return string legacy event name
+     */
+    public static function get_legacy_eventname() {
+        return 'user_created';
+    }
+
+    /**
+     * Return user_created legacy event data.
+     *
+     * @return \stdClass user data.
+     */
+    protected function get_legacy_eventdata() {
+        return $this->get_record_snapshot('user', $this->objectid);
+    }
+
+    /**
+     * Returns array of parameters to be passed to legacy add_to_log() function.
+     *
+     * @return array
+     */
+    protected function get_legacy_logdata() {
+        return array(SITEID, 'user', 'add', '/view.php?id='.$this->objectid, fullname($this->get_legacy_eventdata()));
+    }
+}
diff --git a/lib/classes/event/user_deleted.php b/lib/classes/event/user_deleted.php
new file mode 100644 (file)
index 0000000..545d691
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * User deleted event.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace core\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Event when user profile is deleted.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class user_deleted extends base {
+
+    /**
+     * Initialise required event data properties.
+     */
+    protected function init() {
+        $this->data['objecttable'] = 'user';
+        $this->data['crud'] = 'd';
+        $this->data['level'] = self::LEVEL_OTHER;
+    }
+
+    /**
+     * Returns localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('eventuserdeleted');
+    }
+
+    /**
+     * Returns non-localised event description with id's for admin use only.
+     *
+     * @return string
+     */
+    public function get_description() {
+        $user = (object)$this->other['user'];
+        return 'User profile deleted for user '.$user->firstname.' '.$user->lastname.' id ('.$user->id.')';
+    }
+
+    /**
+     * Return name of the legacy event, which is replaced by this event.
+     *
+     * @return string legacy event name
+     */
+    public static function get_legacy_eventname() {
+        return 'user_deleted';
+    }
+
+    /**
+     * Return user_deleted legacy event data.
+     *
+     * @return \stdClass user data.
+     */
+    protected function get_legacy_eventdata() {
+        return (object)$this->other['user'];
+    }
+
+    /**
+     * Returns array of parameters to be passed to legacy add_to_log() function.
+     *
+     * @return array
+     */
+    protected function get_legacy_logdata() {
+        $user = (object)$this->other['user'];
+        return array(SITEID, 'user', 'delete', "view.php?id=$user->id", $user->firstname.' '.$user->lastname);
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @throws \coding_exception
+     * @return void
+     */
+    protected function validate_data() {
+        parent::validate_data();
+        if (!isset($this->other['user'])) {
+            throw new \coding_exception('user must be set in $other.');
+        }
+    }
+}
diff --git a/lib/classes/event/user_enrolment_created.php b/lib/classes/event/user_enrolment_created.php
new file mode 100644 (file)
index 0000000..d45ca6d
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * User enrolment created event.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace core\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Event when user is enrolled in a course.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class user_enrolment_created extends base {
+
+    /**
+     * Initialise required event data properties.
+     */
+    protected function init() {
+        $this->data['objecttable'] = 'user_enrolments';
+        $this->data['crud'] = 'c';
+        $this->data['level'] = self::LEVEL_TEACHING;
+    }
+
+    /**
+     * Returns localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('eventuserenrolmentcreated', 'core_enrol');
+    }
+
+    /**
+     * Returns non-localised event description with id's for admin use only.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return 'User '.$this->relateduserid. ' is enrolled in course '.$this->courseid.' by user '.$this->userid;
+    }
+
+    /**
+     * Returns relevant URL.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/enrol/users.php', array('id' => $this->courseid));
+    }
+
+    /**
+     * Return name of the legacy event, which is replaced by this event.
+     *
+     * @return string legacy event name
+     */
+    public static function get_legacy_eventname() {
+        return 'user_enrolled';
+    }
+
+    /**
+     * Return user_enrolled legacy event data.
+     *
+     * @return \stdClass
+     */
+    protected function get_legacy_eventdata() {
+        $legacyeventdata = $this->get_record_snapshot('user_enrolments', $this->objectid);
+        $legacyeventdata->enrol = $this->other['enrol'];
+        $legacyeventdata->courseid = $this->courseid;
+        return $legacyeventdata;
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @throws \coding_exception
+     * @return void
+     */
+    protected function validate_data() {
+        parent::validate_data();
+        if (!isset($this->other['enrol'])) {
+            throw new \coding_exception('Enrolment plugin name must be set in $other.');
+        }
+        if (!isset($this->relateduserid)) {
+            throw new \coding_exception('Related user id must be set.');
+        }
+    }
+}
diff --git a/lib/classes/event/user_enrolment_deleted.php b/lib/classes/event/user_enrolment_deleted.php
new file mode 100644 (file)
index 0000000..82e523f
--- /dev/null
@@ -0,0 +1,110 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * User enrolment deleted event.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace core\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Event when user is unenrolled from a course.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class user_enrolment_deleted extends base {
+
+    /**
+     * Initialise required event data properties.
+     */
+    protected function init() {
+        $this->data['objecttable'] = 'user_enrolments';
+        $this->data['crud'] = 'd';
+        $this->data['level'] = self::LEVEL_TEACHING;
+    }
+
+    /**
+     * Returns localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('eventuserenrolmentdeleted', 'core_enrol');
+    }
+
+    /**
+     * Returns non-localised event description with id's for admin use only.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return 'User '.$this->relateduserid. ' is enrolled in course '.$this->courseid.' by user '.$this->userid;
+    }
+
+    /**
+     * Returns relevant URL.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/enrol/users.php', array('id' => $this->courseid));
+    }
+
+    /**
+     * Return name of the legacy event, which is replaced by this event.
+     *
+     * @return string legacy event name
+     */
+    public static function get_legacy_eventname() {
+        return 'user_unenrolled';
+    }
+
+    /**
+     * Return user_unenrolled legacy event data.
+     *
+     * @return \stdClass
+     */
+    protected function get_legacy_eventdata() {
+        return (object)$this->other['userenrolment'];
+    }
+
+
+    /**
+     * Custom validation.
+     *
+     * @throws \coding_exception
+     * @return void
+     */
+    protected function validate_data() {
+        parent::validate_data();
+        if (!isset($this->other['userenrolment'])) {
+            throw new \coding_exception('User enrolment must be set in $other.');
+        }
+        if (!isset($this->other['enrol'])) {
+            throw new \coding_exception('Enrolment plugin name must be set in $other.');
+        }
+        if (!isset($this->relateduserid)) {
+            throw new \coding_exception('Related user id must be set.');
+        }
+    }
+}
diff --git a/lib/classes/event/user_enrolment_updated.php b/lib/classes/event/user_enrolment_updated.php
new file mode 100644 (file)
index 0000000..786f519
--- /dev/null
@@ -0,0 +1,109 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * User enrolment updated event.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace core\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Event when user enrolment is updated.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class user_enrolment_updated extends base {
+
+    /**
+     * Initialise required event data properties.
+     */
+    protected function init() {
+        $this->data['objecttable'] = 'user_enrolments';
+        $this->data['crud'] = 'u';
+        $this->data['level'] = self::LEVEL_TEACHING;
+    }
+
+    /**
+     * Returns localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('eventuserenrolmentupdated', 'core_enrol');
+    }
+
+    /**
+     * Returns non-localised event description with id's for admin use only.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return 'User '.$this->relateduserid. ' has updated enrolment for user '.$this->userid.' in course '.$this->courseid;
+    }
+
+    /**
+     * Returns relevant URL.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/enrol/users.php', array('id' => $this->courseid));
+    }
+
+    /**
+     * Return name of the legacy event, which is replaced by this event.
+     *
+     * @return string legacy event name
+     */
+    public static function get_legacy_eventname() {
+        return 'user_enrol_modified';
+    }
+
+    /**
+     * Return user_enrol_modified legacy event data.
+     *
+     * @return \stdClass
+     */
+    protected function get_legacy_eventdata() {
+        $legacyeventdata = $this->get_record_snapshot('user_enrolments', $this->objectid);
+        $legacyeventdata->enrol = $this->other['enrol'];
+        $legacyeventdata->courseid = $this->courseid;
+        return $legacyeventdata;
+    }
+
+    /**
+     * Custom validation.
+     *
+     * @throws \coding_exception
+     * @return void
+     */
+    protected function validate_data() {
+        parent::validate_data();
+        if (!isset($this->other['enrol'])) {
+            throw new \coding_exception('Enrolment plugin name must be set in $other.');
+        }
+        if (!isset($this->relateduserid)) {
+            throw new \coding_exception('Related user id must be set.');
+        }
+    }
+}
diff --git a/lib/classes/event/user_loggedout.php b/lib/classes/event/user_loggedout.php
new file mode 100644 (file)
index 0000000..f881b47
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * User logout event.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace core\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Event when user logout.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class user_loggedout extends base {
+
+    /**
+     * Initialise required event data properties.
+     */
+    protected function init() {
+        $this->data['objecttable'] = 'user';
+        $this->data['crud'] = 'r';
+        $this->data['level'] = self::LEVEL_OTHER;
+    }
+
+    /**
+     * Returns localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('eventuserloggedout');
+    }
+
+    /**
+     * Returns non-localised event description with id's for admin use only.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return 'User '.$this->objectid.' logged out.';
+    }
+
+    /**
+     * Returns relevant URL.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/user/view.php', array('id' => $this->objectid));
+    }
+
+    /**
+     * Return name of the legacy event, which is replaced by this event.
+     *
+     * @return string legacy event name
+     */
+    public static function get_legacy_eventname() {
+        return 'user_logout';
+    }
+
+    /**
+     * Return user_logout legacy event data.
+     *
+     * @return \stdClass user data.
+     */
+    protected function get_legacy_eventdata() {
+        return $this->get_record_snapshot('user', $this->objectid);
+    }
+
+    /**
+     * Returns array of parameters to be passed to legacy add_to_log() function.
+     *
+     * @return array
+     */
+    protected function get_legacy_logdata() {
+        return array(SITEID, 'user', 'logout', 'view.php?id='.$this->objectid.'&course='.SITEID, $this->objectid, 0,
+            $this->objectid);
+    }
+}
diff --git a/lib/classes/event/user_updated.php b/lib/classes/event/user_updated.php
new file mode 100644 (file)
index 0000000..005ee40
--- /dev/null
@@ -0,0 +1,99 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * User updated event.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+namespace core\event;
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Event when user profile is updated.
+ *
+ * @package    core
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class user_updated extends base {
+
+    /**
+     * Initialise required event data properties.
+     */
+    protected function init() {
+        $this->data['objecttable'] = 'user';
+        $this->data['crud'] = 'u';
+        $this->data['level'] = self::LEVEL_OTHER;
+    }
+
+    /**
+     * Returns localised event name.
+     *
+     * @return string
+     */
+    public static function get_name() {
+        return get_string('eventuserupdated');
+    }
+
+    /**
+     * Returns non-localised event description with id's for admin use only.
+     *
+     * @return string
+     */
+    public function get_description() {
+        return 'User profile updated for userid '.$this->objectid;
+    }
+
+    /**
+     * Returns relevant URL.
+     *
+     * @return \moodle_url
+     */
+    public function get_url() {
+        return new \moodle_url('/user/view.php', array('id' => $this->objectid));
+    }
+
+    /**
+     * Return name of the legacy event, which is replaced by this event.
+     *
+     * @return string legacy event name
+     */
+    public static function get_legacy_eventname() {
+        return 'user_updated';
+    }
+
+    /**
+     * Return user_updated legacy event data.
+     *
+     * @return \stdClass user data.
+     */
+    protected function get_legacy_eventdata () {
+        return $this->get_record_snapshot('user', $this->objectid);
+    }
+
+    /**
+     * Returns array of parameters to be passed to legacy add_to_log() function.
+     *
+     * @return array
+     */
+    protected function get_legacy_logdata() {
+        return array(SITEID, 'user', 'update', 'view.php?id='.$this->objectid, '');
+    }
+}
index 031ac61..8192704 100644 (file)
@@ -95,6 +95,9 @@ function min_fix_utf8($value) {
         error_reporting($olderror ^ E_NOTICE);
     }
 
+    // No null bytes expected in our data, so let's remove it.
+    $value = str_replace("\0", '', $value);
+
     static $buggyiconv = null;
     if ($buggyiconv === null) {
         $buggyiconv = (!function_exists('iconv') or iconv('UTF-8', 'UTF-8//IGNORE', '100'.chr(130).'€') !== '100€');
index 9f36f54..d03f1c3 100644 (file)
@@ -233,4 +233,10 @@ $definitions = array(
         'mode' => cache_store::MODE_REQUEST,
         'persistent' => true,
     ),
+    // Used to store external badges.
+    'externalbadges' => array(
+        'mode' => cache_store::MODE_APPLICATION,
+        'simplekeys' => true,
+        'ttl' => 3600,
+    ),
 );
index b3ba54a..99e5f32 100644 (file)
@@ -36,14 +36,6 @@ defined('MOODLE_INTERNAL') || die();
 /* List of legacy event handlers */
 
 $handlers = array(
-
-    'user_updated' => array (
-        'handlerfile'      => '/lib/badgeslib.php',
-        'handlerfunction'  => 'badges_award_handle_profile_criteria_review',
-        'schedule'         => 'instant',
-        'internal'         => 1,
-    ),
-
 /*
  * portfolio queued event - for non interactive file transfers
  * NOTE: this is a HACK, please do not add any more things like this here
@@ -70,6 +62,10 @@ $observers = array(
     array(
         'eventname'   => '\core\event\course_completed',
         'callback'    => 'core_badges_observer::course_criteria_review',
+    ),
+    array(
+        'eventname'   => '\core\event\user_updated',
+        'callback'    => 'core_badges_observer::profile_criteria_review',
     )
 
 );
index 4000e8e..b4def7a 100644 (file)
@@ -641,6 +641,7 @@ class mssql_native_moodle_database extends moodle_database {
 
             } else {
                 $param = str_replace("'", "''", $param);
+                $param = str_replace("\0", "", $param);
                 $return .= "N'$param'";
             }
 
index 5761c7b..b939e9f 100644 (file)
@@ -719,6 +719,7 @@ class sqlsrv_native_moodle_database extends moodle_database {
                 $return .= $param;
             } else {
                 $param = str_replace("'", "''", $param);
+                $param = str_replace("\0", "", $param);
                 $return .= "N'$param'";
             }
 
index 7ee56f4..b86da9d 100644 (file)
@@ -68,6 +68,13 @@ M.editor_tinymce.init_editor = function(Y, editorid, options) {
                 ed.contentDocument.addEventListener('keydown', function() {
                     ed.contentWindow.focus();
                 });
+
+                // Whenever a touch event is registered against the content document,
+                // reapply focus. This works around an issue with the location caret not
+                // being focusable without use of the Loupe.
+                ed.contentDocument.addEventListener('touchend', function() {
+                    ed.contentWindow.focus();
+                });
             });
         };
     }
index a9741f9..1793749 100644 (file)
@@ -1276,16 +1276,7 @@ abstract class enrol_plugin {
         if ($ue = $DB->get_record('user_enrolments', array('enrolid'=>$instance->id, 'userid'=>$userid))) {
             //only update if timestart or timeend or status are different.
             if ($ue->timestart != $timestart or $ue->timeend != $timeend or (!is_null($status) and $ue->status != $status)) {
-                $ue->timestart    = $timestart;
-                $ue->timeend      = $timeend;
-                if (!is_null($status)) {
-                    $ue->status   = $status;
-                }
-                $ue->modifierid   = $USER->id;
-                $ue->timemodified = time();
-                $DB->update_record('user_enrolments', $ue);
-
-                $updated = true;
+                $this->update_user_enrol($instance, $userid, $status, $timestart, $timeend);
             }
         } else {
             $ue = new stdClass();
@@ -1303,16 +1294,17 @@ abstract class enrol_plugin {
         }
 
         if ($inserted) {
-            // add extra info and trigger event
-            $ue->courseid  = $courseid;
-            $ue->enrol     = $name;
-            events_trigger('user_enrolled', $ue);
-        } else if ($updated) {
-            $ue->courseid  = $courseid;
-            $ue->enrol     = $name;
-            events_trigger('user_enrol_modified', $ue);
-            // resets current enrolment caches
-            $context->mark_dirty();
+            // Trigger event.
+            $event = \core\event\user_enrolment_created::create(
+                    array(
+                        'objectid' => $ue->id,
+                        'courseid' => $courseid,
+                        'context' => $context,
+                        'relateduserid' => $ue->userid,
+                        'other' => array('enrol' => $name)
+                        )
+                    );
+            $event->trigger();
         }
 
         if ($roleid) {
@@ -1389,10 +1381,17 @@ abstract class enrol_plugin {
         $DB->update_record('user_enrolments', $ue);
         context_course::instance($instance->courseid)->mark_dirty(); // reset enrol caches
 
-        // trigger event
-        $ue->courseid  = $instance->courseid;
-        $ue->enrol     = $instance->name;
-        events_trigger('user_enrol_modified', $ue);
+        // Trigger event.
+        $event = \core\event\user_enrolment_updated::create(
+                array(
+                    'objectid' => $ue->id,
+                    'courseid' => $instance->courseid,
+                    'context' => context_course::instance($instance->courseid),
+                    'relateduserid' => $ue->userid,
+                    'other' => array('enrol' => $name)
+                    )
+                );
+        $event->trigger();
     }
 
     /**
@@ -1440,8 +1439,6 @@ abstract class enrol_plugin {
                  WHERE ue.userid = :userid AND e.courseid = :courseid";
         if ($DB->record_exists_sql($sql, array('userid'=>$userid, 'courseid'=>$courseid))) {
             $ue->lastenrol = false;
-            events_trigger('user_unenrolled', $ue);
-            // user still has some enrolments, no big cleanup yet
 
         } else {
             // the big cleanup IS necessary!
@@ -1458,9 +1455,20 @@ abstract class enrol_plugin {
             $DB->delete_records('user_lastaccess', array('userid'=>$userid, 'courseid'=>$courseid));
 
             $ue->lastenrol = true; // means user not enrolled any more
-            events_trigger('user_unenrolled', $ue);
         }
-
+        // Trigger event.
+        $event = \core\event\user_enrolment_deleted::create(
+                array(
+                    'courseid' => $courseid,
+                    'context' => $context,
+                    'relateduserid' => $ue->userid,
+                    'other' => array(
+                        'userenrolment' => (array)$ue,
+                        'enrol' => $name
+                        )
+                    )
+                );
+        $event->trigger();
         // reset all enrol caches
         $context->mark_dirty();
 
index ad04ace..a0fae10 100644 (file)
@@ -1220,6 +1220,8 @@ function fix_utf8($value) {
             // Shortcut.
             return $value;
         }
+        // No null bytes expected in our data, so let's remove it.
+        $value = str_replace("\0", '', $value);
 
         // Lower error reporting because glibc throws bogus notices.
         $olderror = error_reporting();
@@ -3213,11 +3215,7 @@ function require_login($courseorid = null, $autologinguest = true, $cm = null, $
 function require_logout() {
     global $USER;
 
-    $params = $USER;
-
     if (isloggedin()) {
-        add_to_log(SITEID, "user", "logout", "view.php?id=$USER->id&course=".SITEID, $USER->id, 0, $USER->id);
-
         $authsequence = get_enabled_auth_plugins(); // Auths, in sequence.
         foreach ($authsequence as $authname) {
             $authplugin = get_auth_plugin($authname);
@@ -3225,9 +3223,16 @@ function require_logout() {
         }
     }
 
-    events_trigger('user_logout', $params);
+    $event = \core\event\user_loggedout::create(
+            array(
+                'objectid' => $USER->id,
+                'context' => context_user::instance($USER->id)
+                )
+            );
+    $event->trigger();
+
     session_get_instance()->terminate_current();
-    unset($params);
+    unset($GLOBALS['USER']);
 }
 
 /**
@@ -3440,7 +3445,9 @@ function get_user_key($script, $userid, $instance=null, $iprestriction=null, $va
  * @return bool Always returns true
  */
 function update_user_login_times() {
-    global $USER, $DB;
+    global $USER, $DB, $CFG;
+
+    require_once($CFG->dirroot.'/user/lib.php');
 
     if (isguestuser()) {
         // Do not update guest access times/ips for performance.
@@ -3466,7 +3473,7 @@ function update_user_login_times() {
     $USER->lastaccess = $user->lastaccess = $now;
     $USER->lastip = $user->lastip = getremoteaddr();
 
-    $DB->update_record('user', $user);
+    user_update_user($user, false);
     return true;
 }
 
@@ -3965,7 +3972,9 @@ function get_user_fieldnames() {
  */
 function create_user_record($username, $password, $auth = 'manual') {
     global $CFG, $DB;
-    require_once($CFG->dirroot."/user/profile/lib.php");
+    require_once($CFG->dirroot.'/user/profile/lib.php');
+    require_once($CFG->dirroot.'/user/lib.php');
+
     // Just in case check text case.
     $username = trim(core_text::strtolower($username));
 
@@ -4006,7 +4015,7 @@ function create_user_record($username, $password, $auth = 'manual') {
     $newuser->timemodified = $newuser->timecreated;
     $newuser->mnethostid = $CFG->mnet_localhost_id;
 
-    $newuser->id = $DB->insert_record('user', $newuser);
+    $newuser->id = user_create_user($newuser, false);
 
     // Save user profile data.
     profile_save_data($newuser);
@@ -4018,10 +4027,6 @@ function create_user_record($username, $password, $auth = 'manual') {
     // Set the password.
     update_internal_user_password($user, $password);
 
-    // Fetch full user record for the event, the complete user data contains too much info
-    // and we want to be consistent with other places that trigger this event.
-    events_trigger('user_created', $DB->get_record('user', array('id' => $user->id)));
-
     return $user;
 }
 
@@ -4034,6 +4039,7 @@ function create_user_record($username, $password, $auth = 'manual') {
 function update_user_record($username) {
     global $DB, $CFG;
     require_once($CFG->dirroot."/user/profile/lib.php");
+    require_once($CFG->dirroot.'/user/lib.php');
     // Just in case check text case.
     $username = trim(core_text::strtolower($username));
 
@@ -4076,14 +4082,10 @@ function update_user_record($username) {
         if ($newuser) {
             $newuser['id'] = $oldinfo->id;
             $newuser['timemodified'] = time();
-            $DB->update_record('user', $newuser);
+            user_update_user((object) $newuser, false);
 
             // Save user profile data.
             profile_save_data((object) $newuser);
-
-            // Fetch full user record for the event, the complete user data contains too much info
-            // and we want to be consistent with other places that trigger this event.
-            events_trigger('user_updated', $DB->get_record('user', array('id' => $oldinfo->id)));
         }
     }
 
@@ -4141,6 +4143,7 @@ function delete_user(stdClass $user) {
     require_once($CFG->libdir.'/gradelib.php');
     require_once($CFG->dirroot.'/message/lib.php');
     require_once($CFG->dirroot.'/tag/lib.php');
+    require_once($CFG->dirroot.'/user/lib.php');
 
     // Make sure nobody sends bogus record type as parameter.
     if (!property_exists($user, 'id') or !property_exists($user, 'username')) {
@@ -4167,6 +4170,9 @@ function delete_user(stdClass $user) {
         return false;
     }
 
+    // Keep a copy of user context, we need it for event.
+    $usercontext = context_user::instance($user->id);
+
     // Delete all grades - backup is kept in grade_grades_history table.
     grade_user_delete($user->id);
 
@@ -4216,9 +4222,6 @@ function delete_user(stdClass $user) {
     // Force logout - may fail if file based sessions used, sorry.
     session_kill_user($user->id);
 
-    // Now do a final accesslib cleanup - removes all role assignments in user context and context itself.
-    context_helper::delete_instance(CONTEXT_USER, $user->id);
-
     // Workaround for bulk deletes of users with the same email address.
     $delname = "$user->email.".time();
     while ($DB->record_exists('user', array('username' => $delname))) { // No need to use mnethostid here.
@@ -4235,9 +4238,22 @@ function delete_user(stdClass $user) {
     $updateuser->picture      = 0;
     $updateuser->timemodified = time();
 
-    $DB->update_record('user', $updateuser);
-    // Add this action to log.
-    add_to_log(SITEID, 'user', 'delete', "view.php?id=$user->id", $user->firstname.' '.$user->lastname);
+    user_update_user($updateuser, false);
+
+    // Now do a final accesslib cleanup - removes all role assignments in user context and context itself.
+    context_helper::delete_instance(CONTEXT_USER, $user->id);
+
+    // Any plugin that needs to cleanup should register this event.
+    // Trigger event.
+    $event = \core\event\user_deleted::create(
+            array(
+                'objectid' => $user->id,
+                'context' => $usercontext,
+                'other' => array('user' => (array)clone $user)
+                )
+            );
+    $event->add_record_snapshot('user', $updateuser);
+    $event->trigger();
 
     // We will update the user's timemodified, as it will be passed to the user_deleted event, which
     // should know about this updated property persisted to the user's table.
@@ -4247,9 +4263,6 @@ function delete_user(stdClass $user) {
     $authplugin = get_auth_plugin($user->auth);
     $authplugin->user_delete($user);
 
-    // Any plugin that needs to cleanup should register this event.
-    events_trigger('user_deleted', $user);
-
     return true;
 }
 
index 5b6af5c..03f7d22 100644 (file)
@@ -3101,6 +3101,18 @@ class action_menu implements renderable {
      */
     public $attributessecondary = array();
 
+    /**
+     * The string to use next to the icon for the action icon relating to the secondary (dropdown) menu.
+     * @var array
+     */
+    public $actiontext = null;
+
+    /**
+     * An icon to use for the toggling the secondary menu (dropdown).
+     * @var pix_icon
+     */
+    public $actionicon;
+
     /**
      * Constructs the action menu with the given items.
      *
@@ -3128,6 +3140,12 @@ class action_menu implements renderable {
             'aria-labelledby' => 'action-menu-toggle-'.$this->instance,
             'role' => 'menu'
         );
+        $this->actionicon = new pix_icon(
+            't/contextmenu',
+            new lang_string('actions', 'moodle'),
+            'moodle',
+            array('class' => 'iconsmall', 'title' => '')
+        );
         $this->set_alignment(self::TR, self::BR);
         foreach ($actions as $action) {
             $this->add($action);
@@ -3208,14 +3226,18 @@ class action_menu implements renderable {
         if ($output === null) {
             $output = $OUTPUT;
         }
-        $title = get_string('actions', 'moodle');
-        $pixicon = $output->pix_icon(
-            't/contextmenu',
-            $title,
-            'moodle',
-            array('class' => 'iconsmall', 'title' => '')
-        );
-
+        $pixicon = $this->actionicon;
+        $title = new lang_string('actions', 'moodle');
+        if ($pixicon instanceof renderable) {
+            $pixicon = $output->render($pixicon);
+            if ($pixicon instanceof pix_icon && isset($pixicon->attributes['alt'])) {
+                $title = $pixicon->attributes['alt'];
+            }
+        }
+        $string = '';
+        if ($this->actiontext) {
+            $string = $this->actiontext;
+        }
         $actions = $this->primaryactions;
         $attributes = array(
             'class' => 'toggle-display',
@@ -3223,7 +3245,7 @@ class action_menu implements renderable {
             'id' => 'action-menu-toggle-'.$this->instance,
             'role' => 'menuitem'
         );
-        $actions[] = html_writer::link('#', $pixicon, $attributes);
+        $actions[] = html_writer::link('#', $string.$pixicon, $attributes);
         return $actions;
     }
 
@@ -3344,7 +3366,7 @@ class action_menu_link extends action_link implements renderable {
      * @param bool $primary Whether this is a primary action or not.
      * @param array $attributes Any attribtues associated with the action.
      */
-    public function __construct(moodle_url $url, pix_icon $icon, $text, $primary = true, array $attributes = array()) {
+    public function __construct(moodle_url $url, pix_icon $icon = null, $text, $primary = true, array $attributes = array()) {
         parent::__construct($url, $text, null, $attributes, $icon);
         $this->primary = (bool)$primary;
         $this->add_class('menu-action');
@@ -3369,7 +3391,7 @@ class action_menu_link_primary extends action_menu_link {
      * @param string $text
      * @param array $attributes
      */
-    public function __construct(moodle_url $url, pix_icon $icon, $text, array $attributes = array()) {
+    public function __construct(moodle_url $url, pix_icon $icon = null, $text, array $attributes = array()) {
         parent::__construct($url, $icon, $text, true, $attributes);
     }
 }
@@ -3391,7 +3413,7 @@ class action_menu_link_secondary extends action_menu_link {
      * @param string $text
      * @param array $attributes
      */
-    public function __construct(moodle_url $url, pix_icon $icon, $text, array $attributes = array()) {
+    public function __construct(moodle_url $url, pix_icon $icon = null, $text, array $attributes = array()) {
         parent::__construct($url, $icon, $text, false, $attributes);
     }
 }
index e133403..77dbfb8 100644 (file)
@@ -345,6 +345,16 @@ class core_renderer extends renderer_base {
      */
     public function standard_head_html() {
         global $CFG, $SESSION;
+
+        // Before we output any content, we need to ensure that certain
+        // page components are set up.
+
+        // Blocks must be set up early as they may require javascript which
+        // has to be included in the page header before output is created.
+        foreach ($this->page->blocks->get_regions() as $region) {
+            $this->page->blocks->ensure_content_created($region, $this);
+        }
+
         $output = '';
         $output .= '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . "\n";
         $output .= '<meta name="keywords" content="moodle, ' . $this->page->title . '" />' . "\n";
index 310fc0c..ea46e3a 100644 (file)
@@ -44,7 +44,7 @@ class core_configonlylib_testcase extends advanced_testcase {
      */
     public function test_min_fix_utf8() {
         $this->assertSame('abc', min_fix_utf8('abc'));
-        $this->assertSame("žlutý koníček přeskočil potůček \n\t\r\0", min_fix_utf8("žlutý koníček přeskočil potůček \n\t\r\0"));
+        $this->assertSame("žlutý koníček přeskočil potůček \n\t\r", min_fix_utf8("žlutý koníček přeskočil potůček \n\t\r\0"));
         $this->assertSame('aš', min_fix_utf8('a'.chr(130).'š'), 'This fails with buggy iconv() when mbstring extenstion is not available as fallback.');
     }
 
index 1c9fe7e..2a70acc 100644 (file)
@@ -169,8 +169,8 @@ class core_moodlelib_testcase extends advanced_testcase {
         $object->b = 'bb';
         $this->assertEquals($object, fix_utf8($object));
 
-        // Valid utf8 string.
-        $this->assertSame("žlutý koníček přeskočil potůček \n\t\r\0", fix_utf8("žlutý koníček přeskočil potůček \n\t\r\0"));
+        // valid utf8 string
+        $this->assertSame("žlutý koníček přeskočil potůček \n\t\r", fix_utf8("žlutý koníček přeskočil potůček \n\t\r\0"));
 
         // Invalid utf8 string.
         $this->assertSame('aš', fix_utf8('a'.chr(130).'š'), 'This fails with buggy iconv() when mbstring extenstion is not available as fallback.');
@@ -1851,7 +1851,14 @@ class core_moodlelib_testcase extends advanced_testcase {
         $user = $this->getDataGenerator()->create_user(array('idnumber'=>'abc'));
         $user2 = $this->getDataGenerator()->create_user(array('idnumber'=>'xyz'));
 
+        // Delete user and capture event.
+        $sink = $this->redirectEvents();
         $result = delete_user($user);
+        $events = $sink->get_events();
+        $sink->close();
+        $event = array_pop($events);
+
+        // Test user is deleted in DB.
         $this->assertTrue($result);
         $deluser = $DB->get_record('user', array('id'=>$user->id), '*', MUST_EXIST);
         $this->assertEquals(1, $deluser->deleted);
@@ -1862,8 +1869,15 @@ class core_moodlelib_testcase extends advanced_testcase {
 
         $this->assertEquals(1, $DB->count_records('user', array('deleted'=>1)));
 
-        // Try invalid params.
+        // Test Event.
+        $this->assertInstanceOf('\core\event\user_deleted', $event);
+        $this->assertSame($user->id, $event->objectid);
+        $this->assertSame('user_deleted', $event->get_legacy_eventname());
+        $this->assertEventLegacyData($user, $event);
+        $expectedlogdata = array(SITEID, 'user', 'delete', "view.php?id=$user->id", $user->firstname.' '.$user->lastname);
+        $this->assertEventLegacyLogData($expectedlogdata, $event);
 
+        // Try invalid params.
         $record = new stdClass();
         $record->grrr = 1;
         try {
@@ -2407,4 +2421,35 @@ class core_moodlelib_testcase extends advanced_testcase {
         $expectedarray = array('19' => 'second', '38' => 'first', '44' => 'firsthalf');
         $this->assertEquals($expectedarray, order_in_string($valuearray, $formatstring));
     }
+
+    /**
+     * Test require_logout.
+     */
+    public function test_require_logout() {
+        $this->resetAfterTest();
+        $user = $this->getDataGenerator()->create_user();
+        $this->setUser($user);
+        $course = $this->getDataGenerator()->create_course();
+
+        $this->assertTrue(isloggedin());
+
+        // Logout user and capture event.
+        $sink = $this->redirectEvents();
+        require_logout();
+        $events = $sink->get_events();
+        $sink->close();
+        $event = array_pop($events);
+
+        // Check if user is logged out.
+        $this->assertFalse(isloggedin());
+
+        // Test Event.
+        $this->assertInstanceOf('\core\event\user_loggedout', $event);
+        $this->assertSame($user->id, $event->objectid);
+        $this->assertSame('user_logout', $event->get_legacy_eventname());
+        $this->assertEventLegacyData($user, $event);
+        $expectedlogdata = array(SITEID, 'user', 'logout', 'view.php?id='.$event->objectid.'&course='.SITEID, $event->objectid, 0,
+            $event->objectid);
+        $this->assertEventLegacyLogData($expectedlogdata, $event);
+    }
 }
index f91750a..74479fe 100644 (file)
Binary files a/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-debug.js and b/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-debug.js differ
index 71d6e02..692eebf 100644 (file)
Binary files a/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-min.js and b/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue-min.js differ
index f91750a..74479fe 100644 (file)
Binary files a/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue.js and b/lib/yui/build/moodle-core-notification-dialogue/moodle-core-notification-dialogue.js differ
index 1f19cc8..6624784 100644 (file)
@@ -302,6 +302,26 @@ Y.extend(DIALOGUE, Y.Panel, {
     shouldResizeFullscreen : function() {
         return (window === window.parent) && this.get('responsive') &&
                Math.floor(Y.one(document.body).get('winWidth')) < this.get('responsiveWidth');
+    },
+
+    /**
+     * Override the show method to set keyboard focus on the dialogue.
+     *
+     * @method show
+     * @return void
+     */
+    show : function() {
+        var result = null,
+            header = this.headerNode,
+            content = this.bodyNode;
+
+        result = DIALOGUE.superclass.show.call(this);
+        if (header && header !== '') {
+            header.focus();
+        } else if (content && content !== '') {
+            content.focus();
+        }
+        return result;
     }
 }, {
     NAME : DIALOGUE_NAME,
index 51274f4..210994d 100644 (file)
@@ -3914,9 +3914,10 @@ class assign {
                 $team = groups_get_members($submission->groupid, 'u.id');
 
                 foreach ($team as $member) {
-                    $submission->groupid = 0;
-                    $submission->userid = $member->id;
-                    $this->gradebook_item_update($submission, null);
+                    $membersubmission = clone $submission;
+                    $membersubmission->groupid = 0;
+                    $membersubmission->userid = $member->id;
+                    $this->gradebook_item_update($membersubmission, null);
                 }
                 return;
             }
index 7812c26..742b679 100644 (file)
@@ -792,6 +792,16 @@ if ($showactivity) {
         $records = array();
     }
 
+    if ($mode != 'single' && $canmanageentries) {
+        echo html_writer::empty_tag('input', array('type' => 'button', 'id' => 'checkall', 'value' => get_string('selectall')));
+        echo html_writer::empty_tag('input', array('type' => 'button', 'id' => 'checknone', 'value' => get_string('deselectall')));
+        echo html_writer::empty_tag('input', array('class' => 'form-submit', 'type' => 'submit', 'value' => get_string('deleteselected')));
+
+        $module = array('name'=>'mod_data', 'fullpath'=>'/mod/data/module.js');
+        $PAGE->requires->js_init_call('M.mod_data.init_view', null, false, $module);
+    }
+    echo html_writer::end_tag('form');
+
     if ($mode == '' && !empty($CFG->enableportfolios) && !empty($records)) {
         require_once($CFG->libdir . '/portfoliolib.php');
         $button = new portfolio_add_button();
@@ -802,20 +812,8 @@ if ($showactivity) {
         echo $button->to_html(PORTFOLIO_ADD_FULL_FORM);
     }
 
-
     //Advanced search form doesn't make sense for single (redirects list view)
     if (($maxcount || $mode == 'asearch') && $mode != 'single') {
-        if ($canmanageentries) {
-            echo html_writer::start_tag('div', array('class' => 'form-buttons'));
-            echo html_writer::empty_tag('input', array('type' => 'button', 'id' => 'checkall', 'value' => get_string('selectall')));
-            echo html_writer::empty_tag('input', array('type' => 'button', 'id' => 'checknone', 'value' => get_string('deselectall')));
-            echo html_writer::empty_tag('input', array('class' => 'form-submit', 'type' => 'submit', 'value' => get_string('deleteselected')));
-            echo html_writer::end_tag('div');
-
-            $module = array('name'=>'mod_data', 'fullpath'=>'/mod/data/module.js');
-            $PAGE->requires->js_init_call('M.mod_data.init_view', null, false, $module);
-        }
-        echo html_writer::end_tag('form');
         data_print_preference_form($data, $perpage, $search, $sort, $order, $search_array, $advanced, $mode);
     }
 }
diff --git a/mod/forum/classes/observer.php b/mod/forum/classes/observer.php
new file mode 100644 (file)
index 0000000..a41efff
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Event observers used in forum.
+ *
+ * @package    mod_forum
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Event observer for mod_forum.
+ */
+class mod_forum_observer {
+    /**
+     * Triggered via user_enrolment_deleted event.
+     *
+     * @param \core\event\user_enrolment_deleted $event
+     */
+    public static function user_enrolment_deleted(\core\event\user_enrolment_deleted $event) {
+        global $DB;
+
+        // NOTE: this has to be as fast as possible.
+        // Get user enrolment info from event.
+        $cp = (object)$event->other['userenrolment'];
+        if ($cp->lastenrol) {
+            $params = array('userid' => $cp->userid, 'courseid' => $cp->courseid);
+            $forumselect = "IN (SELECT f.id FROM {forum} f WHERE f.course = :courseid)";
+
+            $DB->delete_records_select('forum_digests', 'userid = :userid AND forum '.$forumselect, $params);
+            $DB->delete_records_select('forum_subscriptions', 'userid = :userid AND forum '.$forumselect, $params);
+            $DB->delete_records_select('forum_track_prefs', 'userid = :userid AND forumid '.$forumselect, $params);
+            $DB->delete_records_select('forum_read', 'userid = :userid AND forumid '.$forumselect, $params);
+        }
+    }
+}
index ded6583..5421b5a 100644 (file)
@@ -31,11 +31,13 @@ $handlers = array (
         'schedule'         => 'instant',
         'internal'         => 1,
     ),
+);
 
-    'user_unenrolled' => array (
-        'handlerfile'      => '/mod/forum/lib.php',
-        'handlerfunction'  => 'forum_user_unenrolled',
-        'schedule'         => 'instant',
-        'internal'         => 1,
+// List of observers.
+$observers = array(
+
+    array(
+        'eventname'   => '\core\event\user_enrolment_deleted',
+        'callback'    => 'mod_forum_observer::user_enrolment_deleted',
     ),
 );
index 917bb8a..be0a2ea 100644 (file)
@@ -6289,28 +6289,6 @@ function forum_user_role_assigned($cp) {
     }
 }
 
-/**
- * This function gets run whenever user is unenrolled from course
- *
- * @param stdClass $cp
- * @return void
- */
-function forum_user_unenrolled($cp) {
-    global $DB;
-
-    // NOTE: this has to be as fast as possible!
-
-    if ($cp->lastenrol) {
-        $params = array('userid'=>$cp->userid, 'courseid'=>$cp->courseid);
-        $forumselect = "IN (SELECT f.id FROM {forum} f WHERE f.course = :courseid)";
-
-        $DB->delete_records_select('forum_digests',       "userid = :userid AND forum $forumselect", $params);
-        $DB->delete_records_select('forum_subscriptions', "userid = :userid AND forum $forumselect", $params);
-        $DB->delete_records_select('forum_track_prefs',   "userid = :userid AND forumid $forumselect", $params);
-        $DB->delete_records_select('forum_read',          "userid = :userid AND forumid $forumselect", $params);
-    }
-}
-
 // Functions to do with read tracking.
 
 /**
index 90de875..d5bfb7a 100644 (file)
@@ -168,4 +168,37 @@ class mod_forum_lib_testcase extends advanced_testcase {
             $this->assertContains($course->shortname, array($course1->shortname, $course2->shortname));
         }
     }
+
+    /**
+     * Test user_enrolment_deleted observer.
+     */
+    public function test_user_enrolment_deleted_observer() {
+        global $DB;
+
+        $this->resetAfterTest();
+
+        $metaplugin = enrol_get_plugin('meta');
+        $user1 = $this->getDataGenerator()->create_user();
+        $course1 = $this->getDataGenerator()->create_course();
+        $course2 = $this->getDataGenerator()->create_course();
+        $student = $DB->get_record('role', array('shortname'=>'student'));
+
+        $e1 = $metaplugin->add_instance($course2, array('customint1' => $course1->id));
+        $enrol1 = $DB->get_record('enrol', array('id' => $e1));
+
+        // Enrol user.
+        $metaplugin->enrol_user($enrol1, $user1->id, $student->id);
+        $this->assertEquals(1, $DB->count_records('user_enrolments'));
+
+        // Unenrol user and capture event.
+        $sink = $this->redirectEvents();
+        $metaplugin->unenrol_user($enrol1, $user1->id);
+        $events = $sink->get_events();
+        $sink->close();
+        $event = array_pop($events);
+
+        $this->assertEquals(0, $DB->count_records('user_enrolments'));
+        $this->assertInstanceOf('\core\event\user_enrolment_deleted', $event);
+        $this->assertEquals('user_unenrolled', $event->get_legacy_eventname());
+    }
 }
index a8d6db6..0d6b9dd 100644 (file)
@@ -1296,13 +1296,15 @@ M.core_filepicker.init = function(Y, options) {
         },
         render: function() {
             var client_id = this.options.client_id;
+            var fpid = "filepicker-"+ client_id;
+            var labelid = 'fp-dialog-label_'+ client_id;
             this.fpnode = Y.Node.createWithFilesSkin(M.core_filepicker.templates.generallayout).
-                set('id', 'filepicker-'+client_id);
+                set('id', 'filepicker-'+client_id).set('aria-labelledby', labelid);
             this.mainui = new M.core.dialogue({
                 extraClasses : ['filepicker'],
                 draggable    : true,
                 bodyContent  : this.fpnode,
-                headerContent: M.str.repository.filepicker,
+                headerContent: '<span id="'+ labelid +'">'+ M.str.repository.filepicker +'</span>',
                 centered     : true,
                 modal        : true,
                 visible      : false,
index 566c122..a7fb5c6 100644 (file)
@@ -349,6 +349,7 @@ input#id_externalurl {direction:ltr;}
 .groupmanagementtable #potentialcell {width: 42%;}
 .groupmanagementtable #buttonscell {width: 16%;}
 .groupmanagementtable #buttonscell input {width: 80%;}
+.groupmanagementtable #buttonscell p.arrow_button input {width: auto;min-width: 80%;margin: 0 auto;}
 .groupmanagementtable #removeselect_wrapper,
 .groupmanagementtable #addselect_wrapper {width: 100%;}
 .groupmanagementtable #removeselect_wrapper label,
index 263d5cc..7074b1f 100644 (file)
@@ -388,6 +388,11 @@ a.skip:active {
 .groupmanagementtable #buttonscell {
     width: 16%;
 }
+.groupmanagementtable #buttonscell p.arrow_button input {
+    width: auto;
+    min-width: 80%;
+    margin: 0 auto;
+}
 .groupmanagementtable #removeselect_wrapper,
 .groupmanagementtable #addselect_wrapper {
     width: 100%;
index 94ba119..7c7bc0e 100644 (file)
@@ -1,4 +1,4 @@
-.layout-option-noheader #page-header,.layout-option-nonavbar #page-navbar,.layout-option-nofooter #page-footer,.layout-option-nocourseheader .course-content-header,.layout-option-nocoursefooter .course-content-footer{display:none}.empty-region-side-pre #block-region-side-pre,.empty-region-side-post #block-region-side-post{display:none}.empty-region-side-post #region-bs-main-and-pre.span9{width:100%}.empty-region-side-pre #region-main{float:none;width:100%}.empty-region-side-post.used-region-side-pre #region-main.span8{width:74.46808510638297%;*width:74.41489361702126%}.empty-region-side-post.used-region-side-pre #block-region-side-pre.span4{width:23.404255319148934%;*width:23.351063829787233%}.empty-region-side-post #region-bs-main-and-post.span9 #region-main.span8{width:100%}.dir-ltr,.mdl-left,.dir-rtl .mdl-right{text-align:left}.dir-rtl,.mdl-right,.dir-rtl .mdl-left{text-align:right}#add,#remove,.centerpara,.mdl-align{text-align:center}a.dimmed,a.dimmed:link,a.dimmed:visited,a.dimmed_text,a.dimmed_text:link,a.dimmed_text:visited,.dimmed_text,.dimmed_text a,.dimmed_text a:link,.dimmed_text a:visited,.usersuspended,.usersuspended a,.usersuspended a:link,.usersuspended a:visited,.dimmed_category,.dimmed_category a{color:#999}.activity.label .dimmed_text{opacity:.5;filter:alpha(opacity=50)}.unlist,.unlist li,.inline-list,.inline-list li,.block .list,.block .list li,.section li.activity,.section li.movehere,.tabtree li{padding:0;margin:0;list-style:none}.inline,.inline-list li{display:inline}.notifytiny{font-size:10.5px}.notifytiny li,.notifytiny td{font-size:100%}.red,.notifyproblem{color:#b94a48}.green,.notifysuccess{color:#468847}.reportlink{text-align:right}a.autolink.glossary:hover{cursor:help}.collapsibleregioncaption{white-space:nowrap}.collapsibleregioncaption img{vertical-align:middle}.jsenabled .hiddenifjs{display:none}.visibleifjs{display:none}.jsenabled .visibleifjs{display:inline}.jsenabled .collapsibleregion{overflow:hidden}.jsenabled .collapsed .collapsibleregioninner{visibility:hidden}.yui-overlay .yui-widget-bd{position:relative;top:0;left:0;z-index:1;padding:2px 5px;color:#000;background-color:#ffee69;border:1px solid #a6982b;border-top-color:#d4c237}.clearer{display:block;height:1px;padding:0;margin:0;clear:both;background:transparent;border-width:0}.bold,.warning,.errorbox .title,.pagingbar .title,.pagingbar .thispage,.headingblock{font-weight:bold}img.resize{width:1em;height:1em}.block img.resize,.breadcrumb img.resize{width:.8em;height:.9em}img.icon{width:16px;height:16px;padding-right:6px;vertical-align:text-bottom}.dir-rtl img.icon{padding-right:0;padding-left:6px}img.iconsmall{width:12px;height:12px;margin-right:3px;vertical-align:middle}img.iconhelp,.helplink img{width:16px;height:16px;padding-left:3px;vertical-align:text-bottom}.dir-rtl img.iconhelp,.dir-rtl .helplink img{padding-right:3px;padding-left:0}img.iconlarge{width:24px;height:24px;vertical-align:middle}img.iconsort{padding-left:.3em;margin-bottom:.15em;vertical-align:text-bottom}.dir-rtl img.iconsort{padding-right:.3em;padding-left:0}img.icontoggle{width:50px;height:17px;vertical-align:middle}img.iconkbhelp{width:49px;height:17px}img.icon-pre,.dir-rtl img.icon-post{padding-right:3px;padding-left:0}img.icon-post,.dir-rtl img.icon-pre{padding-right:0;padding-left:3px}.boxaligncenter{margin-right:auto;margin-left:auto}.boxalignright{margin-right:0;margin-left:auto}.boxalignleft{margin-right:auto;margin-left:0}.boxwidthnarrow{width:30%}.boxwidthnormal{width:50%}.boxwidthwide{width:80%}.headermain{font-weight:bold}#maincontent{display:block;height:1px;overflow:hidden}img.uihint{cursor:help}#addmembersform table{margin-right:auto;margin-left:auto}.flexible th{white-space:nowrap}table.flexible .emptyrow{display:none}img.emoticon{width:15px;height:15px;vertical-align:middle}form.popupform,form.popupform div{display:inline}.arrow_button input{overflow:hidden}.action-icon img.smallicon{margin:0 .3em;vertical-align:text-bottom}.main img{vertical-align:middle}.no-overflow{padding-bottom:1px;overflow:auto}.pagelayout-report .no-overflow{overflow:visible}.no-overflow>.generaltable{margin-bottom:0}.accesshide{position:absolute;left:-10000px;font-size:1em;font-weight:normal}.dir-rtl .accesshide{top:-30000px;left:auto}span.hide,div.hide{display:none}a.skip-block,a.skip{position:absolute;top:-1000em;font-size:.85em;text-decoration:none}a.skip-block:focus,a.skip-block:active,a.skip:focus,a.skip:active{position:static;display:block}.skip-block-to{display:block;height:1px;overflow:hidden}.addbloglink{text-align:center}.blog_entry .audience{padding-right:4px;text-align:right}.blog_entry .tags{margin-top:15px}.blog_entry .tags .action-icon img.smallicon{width:16px;height:16px}.blog_entry .content{margin-left:43px}#page-group-index #groupeditform{text-align:center}#doc-contents h1{margin:1em 0 0 0}#doc-contents ul{width:90%;padding:0;margin:0}#doc-contents ul li{list-style-type:none}.groupmanagementtable td{vertical-align:top}.groupmanagementtable #existingcell,.groupmanagementtable #potentialcell{width:42%}.groupmanagementtable #buttonscell{width:16%}.groupmanagementtable #removeselect_wrapper,.groupmanagementtable #addselect_wrapper{width:100%}.groupmanagementtable #removeselect_wrapper label,.groupmanagementtable #addselect_wrapper label{font-weight:normal}.dir-rtl .groupmanagementtable p{text-align:right}#group-usersummary{width:14em}.groupselector{margin-top:3px;margin-bottom:3px}.loginbox{margin:15px;overflow:visible}.loginbox.twocolumns{margin:15px}.loginbox h2,.loginbox .subcontent{padding:10px;margin:5px;text-align:center}.loginbox .loginpanel .desc{padding:0;margin:0;margin-top:15px;margin-bottom:5px}.loginbox .signuppanel .subcontent{text-align:left}.dir-rtl .loginbox .signuppanel .subcontent{text-align:right}.loginbox .loginsub{margin-right:0;margin-left:0}.loginbox .guestsub,.loginbox .forgotsub,.loginbox .potentialidps{margin:5px 12%}.loginbox .potentialidps .potentialidplist{margin-left:40%}.loginbox .potentialidps .potentialidplist div{text-align:left}.loginbox .loginform{margin-top:1em;text-align:left}.loginbox .loginform .form-label{float:left;width:44%;text-align:right;white-space:nowrap;direction:rtl}.dir-rtl .loginbox .loginform .form-label{float:left;width:44%;text-align:right;white-space:nowrap;direction:ltr}.loginbox .loginform .form-input{float:right;width:55%}.loginbox .loginform .form-input input{width:6em}.loginbox .signupform{margin-top:1em;text-align:center}.loginbox.twocolumns .loginpanel,.loginbox.twocolumns .signuppanel{display:block;float:left;width:48%;min-height:30px;padding:0;padding-bottom:2000px;margin:0;margin-bottom:-2000px;margin-left:2.76243%;border:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.loginbox .potentialidp .smallicon{margin:0 .3em;vertical-align:text-bottom}.notepost{margin-bottom:1em}.notepost .userpicture{float:left;margin-right:5px}.notepost .content,.notepost .footer{clear:both}.notesgroup{margin-left:20px}.path-my .coursebox .overview{margin:15px 30px 10px 30px}.path-my .coursebox .info{float:none;margin:0}.mod_introbox{padding:10px}table.mod_index{width:100%}.comment-ctrl{display:none;padding:0;margin:0;font-size:12px}.comment-ctrl h5{padding:5px;margin:0}.comment-area{max-width:400px;padding:5px}.comment-area textarea{width:100%;overflow:auto}.comment-area .fd{text-align:right}.comment-meta span{color:gray}.comment-link img{vertical-align:text-bottom}.comment-list{padding:0;margin:0;overflow:auto;font-size:11px;list-style:none}.comment-list li{position:relative;padding:.3em;margin:2px;margin-bottom:5px;clear:both;list-style:none}.comment-list li.first{display:none}.comment-paging{text-align:center}.comment-paging .pageno{padding:2px}.comment-paging .curpage{border:1px solid #CCC}.comment-message .picture{float:left;width:20px}.dir-rtl .comment-message .picture{float:right}.comment-message .text{padding:0;margin:0}.comment-message .text p{padding:0;margin:0 18px 0 0}.comment-delete{position:absolute;top:0;right:0;margin:.3em}.dir-rtl .comment-delete{position:absolute;right:auto;left:0;margin:.3em}.comment-delete-confirm{width:5em;padding:2px;text-align:center;background:#eee}.comment-container{float:left;margin:4px}.comment-report-selectall{display:none}.comment-link{display:none}.jsenabled .comment-link{display:block}.jsenabled .showcommentsnonjs{display:none}.jsenabled .comment-report-selectall{display:inline}.completion-expired{background:#f2dede}.completion-expected{font-size:10.5px}.completion-sortchoice,.completion-identifyfield{font-size:10.5px;vertical-align:bottom}.completion-progresscell{text-align:right}.completion-expired .completion-expected{font-weight:bold}#page-tag-coursetags_edit .coursetag_edit_centered{position:relative;width:600px;margin:20px auto}#page-tag-coursetags_edit .coursetag_edit_row{clear:both}#page-tag-coursetags_edit .coursetag_edit_row .coursetag_edit_left{float:left;width:50%;text-align:right}#page-tag-coursetags_edit .coursetag_edit_row .coursetag_edit_right{margin-left:50%}#page-tag-coursetags_edit .coursetag_edit_input3{display:none}#page-tag-coursetags_more .coursetag_more_large{font-size:120%}#page-tag-coursetags_more .coursetag_more_small{font-size:80%}#page-tag-coursetags_more .coursetag_more_link{font-size:80%}#tag-description,#tag-blogs{width:100%}#tag-management-box{margin-bottom:10px;line-height:20px}#tag-user-table{width:100%;padding:3px;clear:both}#tag-user-table{*zoom:1}#tag-user-table:before,#tag-user-table:after{display:table;line-height:0;content:""}#tag-user-table:after{clear:both}img.user-image{width:100px;height:100px}#small-tag-cloud-box{width:300px;margin:0 auto}#big-tag-cloud-box{float:none;width:600px;margin:0 auto}ul#tag-cloud-list{padding:5px;margin:0;list-style:none}ul#tag-cloud-list li{display:inline;margin:0;list-style-type:none}#tag-search-box{margin:10px auto;text-align:center}#tag-search-results-container{width:100%;padding:0}#tag-search-results{display:block;float:left;width:60%;padding:0;margin:15px 20% 0 20%}#tag-search-results li{float:left;width:30%;padding-right:1%;padding-left:1%;line-height:20px;text-align:left;list-style:none}span.flagged-tag,span.flagged-tag a{color:#b94a48}table#tag-management-list{width:100%;text-align:left}table#tag-management-list td,table#tag-management-list th{padding:4px;text-align:left;vertical-align:middle}.tag-management-form{text-align:center}#relatedtags-autocomplete-container{width:100%;min-height:4.6em;margin-right:auto;margin-left:auto}#relatedtags-autocomplete{position:relative;display:block;width:60%;margin-right:auto;margin-left:auto}#relatedtags-autocomplete .yui-ac-content{position:absolute;left:20%;z-index:9050;width:420px;overflow:hidden;background:#fff;border:1px solid #404040}#relatedtags-autocomplete .ysearchquery{position:absolute;right:10px;z-index:10;color:#808080}#relatedtags-autocomplete .yui-ac-shadow{position:absolute;z-index:9049;width:100%;margin:.3em;background:#a0a0a0}#relatedtags-autocomplete ul{width:100%;padding:0;margin:0;list-style-type:none}#relatedtags-autocomplete li{padding:0 5px;white-space:nowrap;cursor:default}#relatedtags-autocomplete li.yui-ac-highlight{background:#ffc}h2.tag-heading,div#tag-description,div#tag-blogs,body.tag .managelink{padding:5px}.tag_cloud .s20{font-size:1.5em;font-weight:bold}.tag_cloud .s19{font-size:1.5em}.tag_cloud .s18{font-size:1.4em;font-weight:bold}.tag_cloud .s17{font-size:1.4em}.tag_cloud .s16{font-size:1.3em;font-weight:bold}.tag_cloud .s15{font-size:1.3em}.tag_cloud .s14{font-size:1.2em;font-weight:bold}.tag_cloud .s13{font-size:1.2em}.tag_cloud .s12,.tag_cloud .s11{font-size:1.1em;font-weight:bold}.tag_cloud .s10,.tag_cloud .s9{font-size:1.1em}.tag_cloud .s8,.tag_cloud .s7{font-size:1em;font-weight:bold}.tag_cloud .s6,.tag_cloud .s5{font-size:1em}.tag_cloud .s4,.tag_cloud .s3{font-size:.9em;font-weight:bold}.tag_cloud .s2,.tag_cloud .s1{font-size:.9em}.tag_cloud .s0{font-size:.8em}#webservice-doc-generator td{text-align:left;border:0 solid black}.smartselect{position:absolute}.smartselect .smartselect_mask{background-color:#fff}.smartselect ul{padding:0;margin:0}.smartselect ul li{list-style:none}.smartselect .smartselect_menu{margin-right:5px}.safari .smartselect .smartselect_menu{margin-left:2px}.smartselect .smartselect_menu,.smartselect .smartselect_submenu{display:none;background-color:#FFF;border:1px solid #000}.smartselect .smartselect_menu.visible,.smartselect .smartselect_submenu.visible{display:block}.smartselect .smartselect_menu_content ul li{position:relative;padding:2px 5px}.smartselect .smartselect_menu_content ul li a{color:#333;text-decoration:none}.smartselect .smartselect_menu_content ul li a.selectable{color:inherit}.smartselect .smartselect_submenuitem{background-image:url([[pix:moodle|t/collapsed]]);background-position:100%;background-repeat:no-repeat}.smartselect.spanningmenu .smartselect_submenu{position:absolute;top:-1px;left:100%}.smartselect.spanningmenu .smartselect_submenu a{padding-right:16px;white-space:nowrap}.smartselect.spanningmenu .smartselect_menu_content ul li a.selectable:hover{text-decoration:underline}.smartselect.compactmenu .smartselect_submenu{position:relative;z-index:1010;display:none;margin:2px -3px;margin-left:10px;border-width:0}.smartselect.compactmenu .smartselect_submenu.visible{display:block}.smartselect.compactmenu .smartselect_menu{z-index:1000;overflow:hidden}.smartselect.compactmenu .smartselect_submenu .smartselect_submenu{z-index:1020}.smartselect.compactmenu .smartselect_submenuitem:hover>.smartselect_menuitem_label{font-weight:bold}#page-admin-registration-register .registration_textfield{width:300px}.userenrolment{width:100%;border-collapse:collapse}.userenrolment td{height:41px;padding:0}.userenrolment .subfield{margin-right:5px}.userenrolment .col_userdetails .subfield_picture{float:left}.userenrolment .col_lastseen{width:150px}.userenrolment .col_role{width:262px}.userenrolment .col_role .roles{margin-right:30px}.userenrolment .col_role .role{float:left;padding:3px;margin:3px}.dir-rtl .userenrolment .col_role .role{float:right}.userenrolment .col_role .role a{margin-left:3px;cursor:pointer}.userenrolment .col_role .addrole{float:right;width:18px;height:18px;margin:3px;text-align:center;background-color:#dff0d8;border:1px solid #d6e9c6}.userenrolment .col_role .addrole img{vertical-align:baseline}.userenrolment .hasAllRoles .col_role .addrole{display:none}.userenrolment .col_group .groups{margin-right:30px}.userenrolment .col_group .group{float:left;padding:3px;margin:3px;white-space:nowrap}.userenrolment .col_group .group a{margin-left:3px;cursor:pointer}.userenrolment .col_group .addgroup{float:right;width:18px;height:18px;margin:3px;text-align:center}.userenrolment .col_group .addgroup a img{vertical-align:bottom}.userenrolment .col_enrol .enrolment{float:left;padding:3px;margin:3px}.userenrolment .col_enrol .enrolment a{float:right;margin-left:3px}#page-enrol-users .enrol_user_buttons{float:right}#page-enrol-users.dir-rtl .enrol_user_buttons{float:left}#page-enrol-users .enrol_user_buttons .enrolusersbutton{display:inline;margin-left:1em}#page-enrol-users .enrol_user_buttons .enrolusersbutton div,#page-enrol-users .enrol_user_buttons .enrolusersbutton form{display:inline}#page-enrol-users .enrol_user_buttons .enrolusersbutton input{padding-right:6px;padding-left:6px}#page-enrol-users.dir-rtl .col_userdetails .subfield_picture{float:right}#page-enrol-users .user-enroller-panel .uep-search-results .user .details{width:237px}.dir-rtl .headermain{float:right}.dir-rtl .headermenu{float:left}.dir-rtl .loginbox .loginform .form-label{float:right;text-align:left}.dir-rtl .loginbox .loginform .form-input{text-align:right}.dir-rtl .yui3-menu-hidden{left:0}#page-admin-roles-define.dir-rtl #rolesform .felement{margin-right:180px}#page-message-edit.dir-rtl table.generaltable th.c0{text-align:right}.corelightbox{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;background-color:#CCC}.corelightbox img{position:fixed;top:50%;left:50%}.mod-indent-1{margin-left:30px}.mod-indent-2{margin-left:60px}.mod-indent-3{margin-left:90px}.mod-indent-4{margin-left:120px}.mod-indent-5{margin-left:150px}.mod-indent-6{margin-left:180px}.mod-indent-7{margin-left:210px}.mod-indent-8{margin-left:240px}.mod-indent-9{margin-left:270px}.mod-indent-10{margin-left:300px}.mod-indent-11{margin-left:330px}.mod-indent-12{margin-left:360px}.mod-indent-13{margin-left:390px}.mod-indent-14{margin-left:420px}.mod-indent-15,.mod-indent-huge{margin-left:420px}.dir-rtl .mod-indent-1{margin-right:30px;margin-left:0}.dir-rtl .mod-indent-2{margin-right:60px;margin-left:0}.dir-rtl .mod-indent-3{margin-right:90px;margin-left:0}.dir-rtl .mod-indent-4{margin-right:120px;margin-left:0}.dir-rtl .mod-indent-5{margin-right:150px;margin-left:0}.dir-rtl .mod-indent-6{margin-right:180px;margin-left:0}.dir-rtl .mod-indent-7{margin-right:210px;margin-left:0}.dir-rtl .mod-indent-8{margin-right:240px;margin-left:0}.dir-rtl .mod-indent-9{margin-right:270px;margin-left:0}.dir-rtl .mod-indent-10{margin-right:300px;margin-left:0}.dir-rtl .mod-indent-11{margin-right:330px;margin-left:0}.dir-rtl .mod-indent-12{margin-right:360px;margin-left:0}.dir-rtl .mod-indent-13{margin-right:390px;margin-left:0}.dir-rtl .mod-indent-14{margin-right:420px;margin-left:0}.dir-rtl .mod-indent-15,.dir-rtl .mod-indent-huge{margin-right:420px;margin-left:0}.resourcecontent .mediaplugin_mp3 object{width:600px;height:25px}.resourcecontent audio.mediaplugin_html5audio{width:600px}.resourceimage{max-width:100%}.mediaplugin_mp3 object{width:300px;height:15px}audio.mediaplugin_html5audio{width:300px}.core_media_preview.pagelayout-embedded #content{padding:0}.core_media_preview.pagelayout-embedded #maincontent{height:0}.core_media_preview.pagelayout-embedded .mediaplugin{margin:0}.dir-rtl .ygtvtn,.dir-rtl .ygtvtm,.dir-rtl .ygtvtmh,.dir-rtl .ygtvtmhh,.dir-rtl .ygtvtp,.dir-rtl .ygtvtph,.dir-rtl .ygtvtphh,.dir-rtl .ygtvln,.dir-rtl .ygtvlm,.dir-rtl .ygtvlmh,.dir-rtl .ygtvlmhh,.dir-rtl .ygtvlp,.dir-rtl .ygtvlph,.dir-rtl .ygtvlphh,.dir-rtl .ygtvdepthcell,.dir-rtl .ygtvok,.dir-rtl .ygtvok:hover,.dir-rtl .ygtvcancel,.dir-rtl .ygtvcancel:hover{width:18px;height:22px;cursor:pointer;background-image:url([[pix:theme|yui2-treeview-sprite-rtl]]);background-repeat:no-repeat}.dir-rtl .ygtvtn{background-position:0 -5600px}.dir-rtl .ygtvtm{background-position:0 -4000px}.dir-rtl .ygtvtmh,.dir-rtl .ygtvtmhh{background-position:0 -4800px}.dir-rtl .ygtvtp{background-position:0 -6400px}.dir-rtl .ygtvtph,.dir-rtl .ygtvtphh{background-position:0 -7200px}.dir-rtl .ygtvln{background-position:0 -1600px}.dir-rtl .ygtvlm{background-position:0 0}.dir-rtl .ygtvlmh,.dir-rtl .ygtvlmhh{background-position:0 -800px}.dir-rtl .ygtvlp{background-position:0 -2400px}.dir-rtl .ygtvlph,.dir-rtl .ygtvlphh{background-position:0 -3200px}.dir-rtl .ygtvdepthcell{background-position:0 -8000px}.dir-rtl .ygtvok{background-position:0 -8800px}.dir-rtl .ygtvok:hover{background-position:0 -8844px}.dir-rtl .ygtvcancel{background-position:0 -8822px}.dir-rtl .ygtvcancel:hover{background-position:0 -8866px}.dir-rtl.yui-skin-sam .yui-panel .hd{text-align:right}.dir-rtl .yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd{text-align:right}.dir-rtl .clearlooks2.ie9 .mceAlert .mceMiddle span,.dir-rtl .clearlooks2 .mceConfirm .mceMiddle span{top:44px}.dir-rtl .o2k7Skin table,.dir-rtl .o2k7Skin tbody,.dir-rtl .o2k7Skin a,.dir-rtl .o2k7Skin img,.dir-rtl .o2k7Skin tr,.dir-rtl .o2k7Skin div,.dir-rtl .o2k7Skin td,.dir-rtl .o2k7Skin iframe,.dir-rtl .o2k7Skin span,.dir-rtl .o2k7Skin *,.dir-rtl .o2k7Skin .mceText,.dir-rtl .o2k7Skin .mceListBox .mceText{text-align:right}.path-rating .ratingtable{width:100%;margin-bottom:1em}.path-rating .ratingtable th.rating{width:100%}.path-rating .ratingtable td.rating,.path-rating .ratingtable td.time{text-align:center;white-space:nowrap}.initialbar a{padding-right:2px}.moodle-dialogue-base .moodle-dialogue-lightbox{background-color:#AAA}.moodle-dialogue-base .hidden,.moodle-dialogue-base .moodle-dialogue-hidden{display:none}.no-scrolling{overflow:hidden}.moodle-dialogue-fullscreen{top:0;left:0;width:100%;height:100%;overflow:auto}.moodle-dialogue-base .moodle-dialogue{z-index:600;padding:0;margin:0;background:0;border:0;outline:#000 dotted 0}.moodle-dialogue-base .moodle-dialogue-wrap{margin-top:-3px;margin-left:-3px;background-color:#fff;border:1px solid #ccc;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd{padding:5px;margin:0;font-size:12px;font-weight:normal;letter-spacing:1px;color:#333;text-align:center;text-shadow:1px 1px 1px #fff;background:#ccc;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border-bottom:1px solid #bbb;-webkit-border-radius:10px 10px 0 0;-moz-border-radius:10px 10px 0 0;border-radius:10px 10px 0 0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0);filter:dropshadow(color=#ffffff,offx=1,offy=1)}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd h1{display:inline;padding:0;margin:0;font-size:100%;font-weight:bold}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd .yui3-widget-buttons{padding:5px}.moodle-dialogue-base .closebutton{display:inline-block;float:right;width:25px;height:15px;padding:0;vertical-align:middle;cursor:pointer;background-image:url([[pix:theme|sprite]]);background-repeat:no-repeat;border-style:none}.dir-rtl .moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd .yui3-widget-buttons{right:auto;left:0}.moodle-dialogue-base .moodle-dialogue .moodle-dialogue-bd{padding:1em;overflow:auto;font-size:12px;line-height:2em;color:#555}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-content{padding:0;background:#FFF}.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-hd{padding:10px;font-size:16px}.moodle-dialogue-base .moodle-dialogue-fullscreen,.moodle-dialogue-fullscreen .moodle-dialogue-content{width:100%;height:100%;margin:0;border:0}.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-hd,.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-wrap{border-radius:0}.moodle-dialogue-confirm .confirmation-dialogue{text-align:center}.moodle-dialogue-confirm .confirmation-dialogue input{text-align:center}.moodle-dialogue-exception .moodle-exception-message{text-align:center}.moodle-dialogue-exception .moodle-exception-param label{font-weight:bold}.moodle-dialogue-exception .param-stacktrace label{background-color:#EEE;border:1px solid #ccc;border-bottom-width:0}.moodle-dialogue-exception .param-stacktrace pre{background-color:#fff;border:1px solid #ccc}.moodle-dialogue-exception .param-stacktrace .stacktrace-file{font-size:11.9px;color:navy}.moodle-dialogue-exception .param-stacktrace .stacktrace-line{font-size:11.9px;color:#b94a48}.moodle-dialogue-exception .param-stacktrace .stacktrace-call{font-size:90%;color:#333;border-bottom:1px solid #eee}.moodle-dialogue-base .moodle-dialogue .moodle-dialogue-content .moodle-dialogue-ft{padding:0;margin:.7em 1em;font-size:12px;text-align:right;background-color:#FFF}.moodle-dialogue-confirm .confirmation-message{margin:.5em 1em}.moodle-dialogue-confirm .confirmation-dialogue input{min-width:80px}.moodle-dialogue-exception .moodle-exception-message{margin:1em}.moodle-dialogue-exception .moodle-exception-param{margin-bottom:.5em}.moodle-dialogue-exception .moodle-exception-param label{width:150px}.moodle-dialogue-exception .param-stacktrace label{display:block;padding:4px 1em;margin:0}.moodle-dialogue-exception .param-stacktrace pre{display:block;height:200px;overflow:auto}.moodle-dialogue-exception .param-stacktrace .stacktrace-file{display:inline-block;margin:4px 0}.moodle-dialogue-exception .param-stacktrace .stacktrace-line{display:inline-block;width:50px;margin:4px 1em}.moodle-dialogue-exception .param-stacktrace .stacktrace-call{padding-bottom:4px;padding-left:25px;margin-bottom:4px}.moodle-dialogue .moodle-dialogue-bd .content-lightbox{top:0;left:0;width:100%;height:100%;padding:10% 0;text-align:center;background-color:white;opacity:.75;filter:alpha(opacity=75)}.moodle-dialogue .tooltiptext{max-height:300px}.moodle-dialogue-base .moodle-dialogue.moodle-dialogue-tooltip{z-index:3001}#page-question-edit.dir-rtl a.container-close{right:auto;left:6px}.chooserdialoguebody,.choosertitle{display:none}.moodle-dialogue.chooserdialogue .moodle-dialogue-content .moodle-dialogue-ft{margin:0}.chooserdialogue .moodle-dialogue-wrap .moodle-dialogue-bd{padding:0;background:#f2f2f2;-webkit-border-bottom-right-radius:10px;border-bottom-right-radius:10px;-webkit-border-bottom-left-radius:10px;border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-moz-border-radius-bottomleft:10px}.choosercontainer #chooseform .submitbuttons{margin:.7em 0;text-align:center}.choosercontainer #chooseform .submitbuttons input{min-width:100px;margin:0 .5em}.choosercontainer #chooseform .options{position:relative;border-bottom:1px solid #bbb}.jsenabled .choosercontainer #chooseform .alloptions{max-width:20.3em;overflow-x:hidden;overflow-y:auto;-webkit-box-shadow:inset 0 0 30px 0 #ccc;-moz-box-shadow:inset 0 0 30px 0 #ccc;box-shadow:inset 0 0 30px 0 #ccc}.dir-rtl.jsenabled .choosercontainer #chooseform .alloptions{max-width:18.3em}.choosercontainer #chooseform .moduletypetitle,.choosercontainer #chooseform .option,.choosercontainer #chooseform .nonoption{padding:0 1.6em 0 1.6em;margin-bottom:0}.choosercontainer #chooseform .moduletypetitle{padding-top:1.2em;padding-bottom:.4em;text-transform:uppercase}.choosercontainer #chooseform .option .typename,.choosercontainer #chooseform .option span.modicon img.icon,.choosercontainer #chooseform .nonoption .typename,.choosercontainer #chooseform .nonoption span.modicon img.icon{padding:0 0 0 .5em}.dir-rtl .choosercontainer #chooseform .option .typename,.dir-rtl .choosercontainer #chooseform .option span.modicon img.icon,.dir-rtl .choosercontainer #chooseform .nonoption .typename,.dir-rtl .choosercontainer #chooseform .nonoption span.modicon img.icon{padding:0 .5em 0 0}.choosercontainer #chooseform .option span.modicon img.icon,.choosercontainer #chooseform .nonoption span.modicon img.icon{width:24px;height:24px}.choosercontainer #chooseform .option input[type=radio],.choosercontainer #chooseform .option span.typename,.choosercontainer #chooseform .option span.modicon{vertical-align:middle}.choosercontainer #chooseform .option label{display:block;padding:.3em 0 .1em 0;border-bottom:1px solid #fff}.choosercontainer #chooseform .nonoption{padding-top:.3em;padding-bottom:.1em;padding-left:2.7em}.dir-rtl .choosercontainer #chooseform .nonoption{padding-right:2.7em;padding-left:0}.choosercontainer #chooseform .subtype{padding:0 1.6em 0 3.2em;margin-bottom:0}.dir-rtl .choosercontainer #chooseform .subtype{padding:0 3.2em 0 1.6em}.choosercontainer #chooseform .subtype .typename{margin:0 0 0 .2em}.dir-rtl .choosercontainer #chooseform .subtype .typename{margin:0 .2em 0 0}.jsenabled .choosercontainer #chooseform .instruction,.jsenabled .choosercontainer #chooseform .typesummary{position:absolute;top:0;right:0;bottom:0;left:20.3em;display:none;padding:1.6em;margin:0;overflow-x:hidden;overflow-y:auto;line-height:2em;background-color:#fff}.dir-rtl.jsenabled .choosercontainer #chooseform .instruction,.dir-rtl.jsenabled .choosercontainer #chooseform .typesummary{right:18.5em;left:0;border-right:1px solid grey}.jsenabled .choosercontainer #chooseform .instruction,.choosercontainer #chooseform .selected .typesummary{display:block}.choosercontainer #chooseform .selected{background-color:#fff;-webkit-box-shadow:0 0 10px 0 #ccc;-moz-box-shadow:0 0 10px 0 #ccc;box-shadow:0 0 10px 0 #ccc}.section-modchooser-link img.smallicon{padding:3px}.formlistingradio{padding-right:10px;padding-bottom:25px}.formlistinginputradio{float:left}.formlistingmain{min-height:225px}.formlisting{position:relative;padding:1px 19px 14px;margin:15px 0;background-color:white;border:1px solid #DDD;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.formlistingmore{position:absolute;right:-1px;bottom:-1px;padding:3px 7px;font-size:12px;font-weight:bold;color:#9da0a4;cursor:pointer;background-color:whiteSmoke;border:1px solid #ddd;-webkit-border-radius:4px 0 4px 0;-moz-border-radius:4px 0 4px 0;border-radius:4px 0 4px 0}.formlistingall{padding:0;margin:15px 0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.formlistingrow{top:50%;left:50%;float:left;width:150px;min-height:34px;padding:6px;cursor:pointer;background-color:#f7f7f9;border-right:1px solid #e1e1e8;border-bottom:1px solid;border-left:1px solid #e1e1e8;border-color:#e1e1e8;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}body.jsenabled .formlistingradio{display:none}body.jsenabled .formlisting{display:block}table.collection{width:100%;margin-bottom:20px;border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}table.collection th,table.collection td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}table.collection th{font-weight:bold}table.collection thead th{vertical-align:bottom}table.collection caption+thead tr:first-child th,table.collection caption+thead tr:first-child td,table.collection colgroup+thead tr:first-child th,table.collection colgroup+thead tr:first-child td,table.collection thead:first-child tr:first-child th,table.collection thead:first-child tr:first-child td{border-top:0}table.collection tbody+tbody{border-top:2px solid #ddd}table.collection .table{background-color:#fff}table.collection th,table.collection td{border-left:1px solid #ddd}table.collection caption+thead tr:first-child th,table.collection caption+tbody tr:first-child th,table.collection caption+tbody tr:first-child td,table.collection colgroup+thead tr:first-child th,table.collection colgroup+tbody tr:first-child th,table.collection colgroup+tbody tr:first-child td,table.collection thead:first-child tr:first-child th,table.collection tbody:first-child tr:first-child th,table.collection tbody:first-child tr:first-child td{border-top:0}table.collection thead:first-child tr:first-child>th:first-child,table.collection tbody:first-child tr:first-child>td:first-child,table.collection tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}table.collection thead:first-child tr:first-child>th:last-child,table.collection tbody:first-child tr:first-child>td:last-child,table.collection tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}table.collection thead:last-child tr:last-child>th:first-child,table.collection tbody:last-child tr:last-child>td:first-child,table.collection tbody:last-child tr:last-child>th:first-child,table.collection tfoot:last-child tr:last-child>td:first-child,table.collection tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}table.collection thead:last-child tr:last-child>th:last-child,table.collection tbody:last-child tr:last-child>td:last-child,table.collection tbody:last-child tr:last-child>th:last-child,table.collection tfoot:last-child tr:last-child>td:last-child,table.collection tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}table.collection tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}table.collection tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}table.collection caption+thead tr:first-child th:first-child,table.collection caption+tbody tr:first-child td:first-child,table.collection colgroup+thead tr:first-child th:first-child,table.collection colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}table.collection caption+thead tr:first-child th:last-child,table.collection caption+tbody tr:first-child td:last-child,table.collection colgroup+thead tr:first-child th:last-child,table.collection colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}table.collection tbody>tr:nth-child(odd)>td,table.collection tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}table.collection .name{text-align:left;vertical-align:middle}table.collection .awards{width:10%;text-align:center;vertical-align:middle}table.collection .criteria{width:40%;text-align:left;vertical-align:top}table.collection .badgeimage,table.collection .status{width:15%;text-align:center;vertical-align:middle}table.collection .description{width:25%;text-align:left}table.collection .actions{width:11em;text-align:center;vertical-align:middle}a.criteria-action{float:right;padding:0 3px}table.issuedbadgebox{width:750px;background-color:#fff}table.badgeissuedimage{width:150px;text-align:center}table.badgeissuedinfo{width:600px}table.badgeissuedinfo .bvalue{text-align:left;vertical-align:middle}table.badgeissuedinfo .bfield{width:125px;font-style:italic;text-align:left}ul.badges{margin:0;list-style:none}.badges li{position:relative;display:inline-block;width:150px;padding-bottom:2em;text-align:center;vertical-align:top}.badges li .badge-name{display:block;padding:5px}.badges li>img{position:absolute}.badges li .badge-image{top:0;left:10px;z-index:1;width:90px;height:90px}.badges li .badge-actions{position:relative}div.badge{position:relative;display:block}div.badge .expireimage{top:0;left:20px;width:100px;height:100px}.expireimage{position:absolute;top:0;left:30px;z-index:10;width:90px;height:90px;opacity:.85;filter:alpha(opacity=85)}.badge-profile{vertical-align:top}.connected{color:#468847}.notconnected{color:#b94a48}#page-badges-award .recipienttable tr td{vertical-align:top}#page-badges-award .recipienttable tr td.actions .actionbutton{width:100%;padding:.5em 0;margin:.3em 0}#page-badges-award .recipienttable tr td.existing,#page-badges-award .recipienttable tr td.potential{width:42%}.statustable{margin-bottom:0}.statusbox.active{background-color:#dff0d8}.statusbox.inactive{background-color:#fcf8e3}.activatebadge{margin:0;text-align:left;vertical-align:middle}.addcourse{float:right}.invisiblefieldset{display:inline;padding:0;margin:0;border-width:0}.breadcrumb-nav{float:left;margin-bottom:10px}.dir-rtl .breadcrumb-nav{float:right}.breadcrumb-button .singlebutton div{margin-right:0}.breadcrumb-nav .breadcrumb{margin:0}.moodle-actionmenu,.moodle-actionmenu>ul,.moodle-actionmenu>ul>li{display:inline-block}.moodle-actionmenu ul{padding:0;margin:0;list-style-type:none}.moodle-actionmenu .toggle-display,.moodle-actionmenu .menu-action-text{display:none}.jsenabled .moodle-actionmenu[data-enhance]{display:block}.jsenabled .moodle-actionmenu[data-enhance] .menu{display:none}.jsenabled .moodle-actionmenu[data-enhance] .toggle-display{display:inline;opacity:.5;filter:alpha(opacity=50)}.jsenabled .moodle-actionmenu[data-enhanced] .toggle-display{opacity:1;filter:alpha(opacity=100)}.jsenabled .moodle-actionmenu[data-enhanced] .menu-action-text{display:inline}.moodle-actionmenu[data-enhanced].show{position:relative}.moodle-actionmenu[data-enhanced].show .menu{position:absolute;z-index:1000;display:block;text-align:left;background-color:#fff;border:1px solid #ccc;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}.moodle-actionmenu[data-enhanced].show .menu a{display:block;padding:2px 1em 2px .5em;color:#333}.moodle-actionmenu[data-enhanced].show .menu a:hover,.moodle-actionmenu[data-enhanced].show .menu a:focus{color:#fff;background-color:#08c}.moodle-actionmenu[data-enhanced].show .menu a:first-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.moodle-actionmenu[data-enhanced].show .menu a:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.moodle-actionmenu[data-enhanced].show .menu a.hidden{display:none}.moodle-actionmenu[data-enhanced].show .menu img{vertical-align:middle}.moodle-actionmenu[data-enhanced].show .menu .iconsmall{margin-right:8px}.moodle-actionmenu[data-enhanced].show .menu>li{display:block}.moodle-actionmenu[data-enhanced].show .menu.align-tl-bl{top:100%;left:0;margin-top:4px}.moodle-actionmenu[data-enhanced].show .menu.align-tr-bl{top:100%;right:100%}.moodle-actionmenu[data-enhanced].show .menu.align-bl-bl{bottom:100%;left:0}.moodle-actionmenu[data-enhanced].show .menu.align-br-bl{right:100%;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-br{top:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tr-br{top:100%;right:0;margin-top:4px}.moodle-actionmenu[data-enhanced].show .menu.align-bl-br{bottom:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-br-br{right:0;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-tl{top:0;left:0}.moodle-actionmenu[data-enhanced].show .menu.align-tr-tl{top:0;right:100%;margin-right:4px}.moodle-actionmenu[data-enhanced].show .menu.align-bl-tl{bottom:100%;left:0;margin-bottom:4px}.moodle-actionmenu[data-enhanced].show .menu.align-br-tl{right:100%;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-tr{top:0;left:100%;margin-left:4px}.moodle-actionmenu[data-enhanced].show .menu.align-tr-tr{top:0;right:0}.moodle-actionmenu[data-enhanced].show .menu.align-bl-tr{bottom:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-br-tr{right:0;bottom:100%;margin-bottom:4px}.action-menu-shown .moodle-actionmenu[data-enhanced] .toggle-display{background-color:#FFF}.block .moodle-actionmenu{text-align:right}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu{right:auto;left:0;text-align:right}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu .iconsmall{margin-right:0;margin-left:8px}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-bl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-bl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-bl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-bl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-br{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-br{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-br{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-br{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-tl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-tl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-tl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-tl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-tr{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-tr{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-tr{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-tr{right:auto;left:0}.dir-rtl .block .moodle-actionmenu{text-align:right}ul.dragdrop-keyboard-drag li{list-style-type:none}.block-control-actions .moodle-core-dragdrop-draghandle img{width:12px;height:12px}.formtable tbody th{font-weight:normal;text-align:right}.path-admin #assignrole{width:60%;margin-right:auto;margin-left:auto}.path-admin .admintable .leftalign{text-align:left}.environmenttable p.warn{color:#c09853;background-color:#fcf8e3}.environmenttable .error,.environmenttable span.warn,.environmenttable .ok{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.environmenttable .error:empty,.environmenttable span.warn:empty,.environmenttable .ok:empty{display:none}.environmenttable .error-important,.environmenttable span.warn-important,.environmenttable .ok-important{background-color:#b94a48}.environmenttable .error-important[href],.environmenttable span.warn-important[href],.environmenttable .ok-important[href]{background-color:#953b39}.environmenttable .error-warning,.environmenttable span.warn-warning,.environmenttable .ok-warning{background-color:#f89406}.environmenttable .error-warning[href],.environmenttable span.warn-warning[href],.environmenttable .ok-warning[href]{background-color:#c67605}.environmenttable .error-success,.environmenttable span.warn-success,.environmenttable .ok-success{background-color:#468847}.environmenttable .error-success[href],.environmenttable span.warn-success[href],.environmenttable .ok-success[href]{background-color:#356635}.environmenttable .error-info,.environmenttable span.warn-info,.environmenttable .ok-info{background-color:#3a87ad}.environmenttable .error-info[href],.environmenttable span.warn-info[href],.environmenttable .ok-info[href]{background-color:#2d6987}.environmenttable .error-inverse,.environmenttable span.warn-inverse,.environmenttable .ok-inverse{background-color:#333}.environmenttable .error-inverse[href],.environmenttable span.warn-inverse[href],.environmenttable .ok-inverse[href]{background-color:#1a1a1a}.environmenttable .error{background-color:#b94a48}.environmenttable span.warn{background-color:#f89406}.environmenttable .ok{background-color:#468847}.path-admin .admintable.environmenttable .name,.path-admin .admintable.environmenttable .info,.path-admin #assignrole .admintable .role,.path-admin #assignrole .admintable .userrole,.path-admin #assignrole .admintable .roleholder{white-space:nowrap}.path-admin .incompatibleblockstable td.c0{font-weight:bold}#page-admin-course-category .addcategory{padding:10px}#page-admin-course-index .editcourse{margin:20px auto}#page-admin-course-index .editcourse th,#page-admin-course-index .editcourse td{padding-right:10px;padding-left:10px}.timewarninghidden{display:none}.statusok,.statuswarning,.statusserious,.statuscritical{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.statusok:empty,.statuswarning:empty,.statusserious:empty,.statuscritical:empty{display:none}.statusok-important,.statuswarning-important,.statusserious-important,.statuscritical-important{background-color:#b94a48}.statusok-important[href],.statuswarning-important[href],.statusserious-important[href],.statuscritical-important[href]{background-color:#953b39}.statusok-warning,.statuswarning-warning,.statusserious-warning,.statuscritical-warning{background-color:#f89406}.statusok-warning[href],.statuswarning-warning[href],.statusserious-warning[href],.statuscritical-warning[href]{background-color:#c67605}.statusok-success,.statuswarning-success,.statusserious-success,.statuscritical-success{background-color:#468847}.statusok-success[href],.statuswarning-success[href],.statusserious-success[href],.statuscritical-success[href]{background-color:#356635}.statusok-info,.statuswarning-info,.statusserious-info,.statuscritical-info{background-color:#3a87ad}.statusok-info[href],.statuswarning-info[href],.statusserious-info[href],.statuscritical-info[href]{background-color:#2d6987}.statusok-inverse,.statuswarning-inverse,.statusserious-inverse,.statuscritical-inverse{background-color:#333}.statusok-inverse[href],.statuswarning-inverse[href],.statusserious-inverse[href],.statuscritical-inverse[href]{background-color:#1a1a1a}.statusok{background-color:#468847}.statuswarning{background-color:#c09853}.statusserious{background-color:#f89406}.statuscritical{background-color:#b94a48}#page-admin-report-capability-index #capabilitysearch{width:30em}#page-admin-report-backups-index .backup-error,#page-admin-report-backups-index .backup-unfinished{color:#b94a48}#page-admin-report-backups-index .backup-skipped,#page-admin-report-backups-index .backup-ok{color:#468847}#page-admin-report-backups-index .backup-warning{color:#c09853}#page-admin-qtypes .disabled,#page-admin-qbehaviours .disabled{color:#999}#page-admin-qtypes #qtypes div,#page-admin-qtypes #qtypes form,#page-admin-qbehaviours #qbehaviours div,#page-admin-qbehaviours #qbehaviours form{display:inline}#page-admin-qtypes #qtypes img.spacer,#page-admin-qbehaviours #qbehaviours img.spacer{width:16px}img.iconsmall{padding:.3em;margin:0}#page-admin-qbehaviours .cell.c3,#page-admin-qtypes .cell.c3{font-size:10.5px}#page-admin-lang .generalbox,#page-admin-course-index .singlebutton,#page-admin-course-index .addcategory,#page-course-index .buttons,#page-course-index-category .buttons,#page-admin-course-category .addcategory,#page-admin-stickyblocks .generalbox,#page-admin-maintenance .buttons,#page-admin-course-index .buttons,#page-admin-course-category .buttons,#page-admin-index .copyright,#page-admin-index .copyrightnotice,#page-admin-index .adminerror,#page-admin-index .availableupdatesinfo,#page-admin-index .adminerror .singlebutton,#page-admin-index .adminwarning .singlebutton,#page-admin-index #layout-table .singlebutton{margin-bottom:1em;text-align:center}.path-admin-roles .capabilitysearchui{margin-right:auto;margin-left:auto;text-align:left}#page-admin-roles-define .topfields{margin:1em 0 2em}#page-admin-roles-define .capdefault{background-color:#eee;border:1px solid #cecece}#page-filter-manage .backlink,.path-admin-roles .backlink{margin-top:1em}#page-admin-roles-explain #chooseuser h3,#page-admin-roles-usersroles .contextname{margin-top:0}#page-admin-roles-explain #chooseusersubmit{margin-top:0;text-align:center}#page-admin-roles-usersroles p{margin:0}#page-admin-roles-override .cell.c1,#page-admin-roles-assign .cell.c3,#page-admin-roles-assign .cell.c1{padding-top:.75em}#page-admin-roles-override .overridenotice,#page-admin-roles-define .definenotice{margin:1em 10% 2em 10%;text-align:left}#notice{width:60%;min-width:220px;margin:auto}#page-admin-index .releasenoteslink,#page-admin-index .adminwarning,#page-admin-index .maturitywarning,#page-admin-index .maturityinfo{width:60%;min-width:220px;padding:8px 35px 8px 14px;margin:auto;margin-bottom:20px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}#page-admin-index .maturitywarning,#page-admin-index .adminwarning.maturityinfo.maturity50{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}#page-admin-index .adminwarning.availableupdatesinfo,#page-admin-index .releasenoteslink{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo span{display:block}#page-admin-index .updateplugin div,#page-admin-plugins .updateplugin div{margin-bottom:.5em}#page-admin-index .updateplugin .updatepluginconfirmexternal,#page-admin-plugins .updateplugin .updatepluginconfirmexternal{padding:1em;background-color:#f2dede;border:1px solid #eed3d7}#page-admin-user-user_bulk #users .fgroup{white-space:nowrap}#page-admin-report-stats-index .graph{margin-bottom:1em;text-align:center}#page-admin-report-courseoverview-index .graph{margin-bottom:1em;text-align:center}#page-admin-lang .translator{border-style:solid;border-width:1px}.path-admin .roleassigntable{width:100%}.path-admin .roleassigntable td{padding:.2em .3em;vertical-align:top}.path-admin .roleassigntable p{margin:.2em 0;text-align:left}.path-admin .roleassigntable #existingcell,.path-admin .roleassigntable #potentialcell{width:42%}.path-admin .roleassigntable #existingcell p>label:first-child,.path-admin .roleassigntable #potentialcell p>label:first-child{font-weight:bold}.path-admin .roleassigntable #buttonscell{width:16%}.path-admin .roleassigntable #buttonscell #assignoptions{font-size:10.5px}.path-admin .roleassigntable #removeselect_wrapper,.path-admin .roleassigntable #addselect_wrapper{width:100%}.path-admin table.rolecap tr.rolecap th{font-weight:normal;text-align:left}.path-admin.dir-rtl table.rolecap tr.rolecap th{text-align:right}.path-admin .rolecap .hiddenrow{display:none}.path-admin #defineroletable .rolecap .inherit,.path-admin #defineroletable .rolecap .allow,.path-admin #defineroletable .rolecap .prevent,.path-admin #defineroletable .rolecap .prohibit{min-width:3.5em;padding:0;text-align:center}.path-admin .rolecap .cap-name,.path-admin .rolecap .note{display:block;font-size:10.5px;font-weight:normal;white-space:nowrap}.path-admin .rolecap label{display:block;padding:.5em;margin:0;text-align:center}.plugincheckwrapper{width:100%}.environmentbox{margin-top:1em}#mnetconfig table{margin-right:auto;margin-left:auto}.environmenttable .cell{padding:.15em .5em}.environmenttable img.iconhelp{padding-right:.3em}.dir-rtl .environmenttable img.iconhelp{padding-right:0;padding-left:.3em}#trustedhosts .generaltable{width:500px;margin-right:auto;margin-left:auto}#trustedhosts .standard{width:auto}#adminsettings legend{display:none}#adminsettings fieldset.error{margin:.2em 0 .5em 0}#adminsettings fieldset.error legend{display:block}.dir-rtl #admin-spelllanguagelist textarea,#page-admin-setting-editorsettingstinymce.dir-rtl .form-textarea textarea{text-align:left;direction:ltr}.adminsettingsflags{float:right}.dir-rtl .adminsettingsflags{float:left}.adminsettingsflags label{margin-right:7px}.dir-rtl .adminsettingsflags label{margin-left:7px}.form-description{clear:right}.dir-rtl .form-description{clear:left}.form-item .form-setting .form-htmlarea{display:inline;width:640px}.form-item .form-setting .form-htmlarea .htmlarea{display:block;width:640px}.form-item .form-setting .form-multicheckbox ul{padding:0;margin:7px 0 0 0;list-style:none}.form-item .form-setting .defaultsnext{display:inline;margin-right:.5em}.dir-rtl .form-item .form-setting .defaultsnext{margin-right:0;margin-left:.5em}.form-item .form-setting .locked-checkbox{display:inline;margin-right:.2em;margin-left:.5em}.dir-rtl .form-item .form-setting .locked-checkbox{display:inline;margin-right:.5em;margin-left:.2em}.form-item .form-setting .form-password .unmask,.form-item .form-setting .form-defaultinfo{display:inline-block}.form-item .pathok,.form-item .patherror{margin-left:.5em}#admin-devicedetectregex table{border:0}#admin-emoticons td input{width:8em}#admin-emoticons td.c0 input{width:4em}#adminthemeselector .selectedtheme td.c0{border:1px solid;border-right-width:0}#adminthemeselector .selectedtheme td.c1{border:1px solid;border-left-width:0}.admin_colourpicker,.admin_colourpicker_preview{display:none}.jsenabled .admin_colourpicker_preview{display:inline}.jsenabled .admin_colourpicker{display:block;width:410px;height:102px;margin-bottom:10px}.admin_colourpicker .loadingicon{margin-left:auto;vertical-align:middle}.admin_colourpicker .colourdialogue{float:left;border:1px solid #000}.admin_colourpicker .previewcolour{margin-left:301px;border:1px solid #000}.admin_colourpicker .currentcolour{margin-left:301px;border:1px solid #000;border-top-width:0}.dir-rtl .form-item .form-setting,.dir-rtl .form-item .form-label,.dir-rtl .form-item .form-description,.dir-rtl.path-admin .roleassigntable p{text-align:right}#page-admin-index #notice .checkforupdates{text-align:center}#plugins-check-info{margin:1em;text-align:center}#plugins-check .displayname .pluginicon{width:16px}#plugins-check .status-new .status{background-color:#dff0d8}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity200 .info.release,#plugins-check .status-upgrade .status,#plugins-check .status-delete .status{background-color:#d9edf7}#plugins-control-panel .extension .source,#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity100 .info.release,#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity150 .info.release,.pluginupdateinfo.maturity100,.pluginupdateinfo.maturity150,#plugins-check .extension .source{background-color:#fcf8e3}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity50 .info.release,.pluginupdateinfo.maturity50,#plugins-check .requires-failed,#plugins-check .missingfromdisk .displayname,#plugins-check .status-missing .status,#plugins-check .status-downgrade .status{background-color:#f2dede}#plugins-control-panel .statusmsg{padding:3px;background-color:#eee;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#plugins-control-panel .status-missing .pluginname{background-color:#f2dede}#plugins-control-panel .status-missing .statusmsg{color:#b94a48}#plugins-control-panel .status-new .pluginname{background-color:#dff0d8}#plugins-control-panel .status-new .statusmsg{color:#468847}#plugins-control-panel .disabled .availability{background-color:#eee}#plugins-check .standard .source,#plugins-check .status-nodb .status,#plugins-check .status-uptodate .status,#plugins-check .requires-ok{color:#999}#plugins-check .requires ul{margin:0;font-size:10.5px}#plugins-check .status .pluginupdateinfo{padding:5px 10px;margin:10px;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-check .status .pluginupdateinfo span,#plugins-check .status .pluginupdateinfo a{padding-right:1em}#page-admin-index .upgradepluginsinfo{text-align:center}#page-admin-plugins .checkforupdates{margin:0 auto 1em;text-align:center}#plugins-control-panel .requiredby,#plugins-control-panel .pluginname .componentname{font-size:11.9px;color:#999}#plugins-control-panel .pluginname .componentname{margin-left:22px}#plugins-overview-filter .filter-item,#plugins-overview-panel .info{padding:0 10px}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo .separator,#plugins-check .status .pluginupdateinfo .separator,#page-admin-plugins .separator{border-left:1px dotted #999}#plugins-control-panel .msg td{text-align:center}#plugins-overview-filter,#plugins-overview-panel{margin:1em auto;text-align:center}#plugins-overview-panel .info.updatable{margin-left:10px;font-weight:bold;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-overview-filter .filter-item.active{font-weight:bold}#plugins-control-panel .displayname img.icon{padding-top:0;padding-bottom:0}#plugins-control-panel .uninstall a{color:#b94a48}#plugins-control-panel .notes .pluginupdateinfo{padding:5px 10px;margin:10px;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-control-panel .notes .pluginupdateinfo span,#plugins-control-panel .notes .pluginupdateinfo a{padding-right:1em}.dir-rtl #plugins-check .pluginupdateinfo{text-align:center;direction:ltr}.dir-rtl #plugins-check .rootdir,.dir-rtl #plugins-check .requires-ok{text-align:left;direction:ltr}#page-admin-mnet-peers .box.deletedhosts{margin-bottom:1em;font-size:11.9px}#page-admin-mnet-peers .mform .certdetails{background-color:white}#page-admin-mnet-peers .mform .deletedhostinfo{padding:4px;margin-bottom:5px;background-color:#f2dede;border:2px solid #eed3d7}#core-cache-plugin-summaries table,#core-cache-store-summaries table{width:100%}#core-cache-lock-summary table,#core-cache-definition-summaries table,#core-cache-mode-mappings table{margin:0 auto}#core-cache-store-summaries .default-store td{font-style:italic;color:#333}#core-cache-rescan-definitions,#core-cache-mode-mappings .edit-link,#core-cache-lock-summary .new-instance{margin-top:.5em;text-align:center}.tinymcesubplugins img.icon{padding-top:0;padding-bottom:0}#page-admin-roles-assign div.box.generalbox{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;color:#b94a48;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;background-color:#f2dede;border:1px solid #fbeed5;border-color:#eed3d7;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.calendartable{width:100%}.calendartable th,.calendartable td{width:14%;text-align:center;vertical-align:top;border:0}.calendar_event_course{background-color:#ffd3bd}.calendar_event_global{background-color:#d6f8cd}.calendar_event_group{background-color:#fee7ae}.calendar_event_user{background-color:#dce7ec}.path-calendar .calendar-controls .previous,.path-calendar .calendar-controls .next,.path-calendar .calendar-controls .current{display:block;float:left;width:12%}.path-calendar .calendar-controls .previous{text-align:left}.path-calendar .calendar-controls .current{width:76%;text-align:center}.path-calendar .calendar-controls .next{text-align:right}.path-calendar .maincalendar{padding:0;vertical-align:top}.path-calendar .maincalendar .bottom{padding:5px 0 0 0;text-align:center}.path-calendar .maincalendar .heightcontainer{position:relative;height:100%}.path-calendar .maincalendar .calendarmonth{width:98%;margin:10px auto}.path-calendar .maincalendar .calendarmonth ul{margin:0}.path-calendar .maincalendar .calendarmonth ul li{margin-top:4px;list-style-type:none}.path-calendar .maincalendar .calendarmonth td{height:5em}.path-calendar .maincalendar .calendar-controls .previous,.path-calendar .maincalendar .calendar-controls .next{width:30%}.path-calendar .maincalendar .calendar-controls .current{width:39.95%}.path-calendar .maincalendar .controls{width:98%;margin:10px auto}.path-calendar .maincalendar .eventlist .event{width:100%;margin-bottom:10px;border-collapse:separate;border-spacing:0;border-style:solid;border-width:1px}.path-calendar .maincalendar .eventlist .event .topic .name{float:left}.dir-rtl.path-calendar .maincalendar .eventlist .event .topic .name,.path-calendar .maincalendar .eventlist .event .topic .date{float:right}.dir-rtl.path-calendar .maincalendar .eventlist .event .topic .date{float:left}.path-calendar .maincalendar .eventlist .event .subscription,.path-calendar .maincalendar .eventlist .event .course{float:left;clear:left}.dir-rtl.path-calendar .maincalendar .eventlist .event .subscription,.dir-rtl.path-calendar .maincalendar .eventlist .event .course{float:right;clear:right}.path-calendar .maincalendar .eventlist .event .side{width:32px}.path-calendar .maincalendar .eventlist .event .commands a{margin:0 3px}.path-calendar .maincalendar .header{overflow:hidden}.path-calendar .maincalendar .header .buttons{float:right}.dir-rtl.path-calendar .maincalendar .header .buttons{float:left}.path-calendar .filters table{width:100%;border-collapse:separate;border-spacing:2px}#page-calendar-export .indent{padding-left:20px}.path-calendar .cal_courses_flt label{margin-right:.45em}.dir-rtl.path-calendar .cal_courses_flt label{margin-right:0;margin-left:.45em}.block .minicalendar th,.block .minicalendar td{padding:2px;font-size:.8em}.block .minicalendar{max-width:280px;margin-right:auto;margin-left:auto}.block .minicalendar td.weekend{color:#A00}.block .calendar-controls .previous{display:block;float:left;width:12%;text-align:left}.block .calendar-controls .current{display:block;float:left;width:76%;text-align:center}.block .calendar-controls .next{display:block;float:left;width:12%;text-align:right}.block .calendar_filters ul{margin:0;list-style:none}.block .calendar_filters li{margin-bottom:.2em}.block .calendar_filters li span img{padding:0 .2em}.block .calendar_filters .eventname{padding-left:.2em}.dir-rtl .block .calendar_filters .eventname{padding-right:.2em;padding-left:0}.block .content h3.eventskey{margin-top:.5em}@media(min-width:768px){#page-calender-view .container fluid{min-width:1024px}}.section_add_menus{text-align:right}.dir-rtl .section_add_menus{text-align:left}.section_add_menus .horizontal div,.section_add_menus .horizontal form{display:inline}.section_add_menus optgroup{font-style:italic;font-weight:normal}.section_add_menus .urlselect{margin-left:.4em}.dir-rtl .section_add_menus .urlselect{margin-right:.4em;margin-left:0}.section_add_menus .urlselect select{margin-left:.2em}.dir-rtl .section_add_menus .urlselect select{margin-right:.2em;margin-left:0}.section_add_menus .urlselect img.iconhelp{padding:0;margin:0;vertical-align:text-bottom}.site-topic ul.section,.course-content ul.section{margin:1em}.section .activity img.activityicon{margin-right:6px}.dir-rtl .section .activity img.activityicon{margin-right:0;margin-left:6px}.section .activity .activityinstance,.section .activity .activityinstance div{display:inline-block}.editing .section .activity .activityinstance{min-width:40%}.section .activity .activityinstance>a{display:block}.editing_show+.editing_assign,.editing_hide+.editing_assign{margin-left:20px}.section .activity .commands{display:inline;white-space:nowrap}.section .activity.modtype_label .commands{padding-left:22px;margin-left:40%}.section .activity.modtype_label.label{font-weight:normal}.section li.activity{padding:.2em;clear:both}.section .activity .activityinstance .groupinglabel{padding-left:30px}.dir-rtl .section .activity .activityinstance .groupinglabel{padding-right:30px}.section .activity .availabilityinfo,.section .activity .contentafterlink{margin-top:.5em;margin-left:30px}.dir-rtl .section .activity .availabilityinfo,.dir-rtl .section .activity .contentafterlink{margin-right:30px;margin-left:0}.section .activity .contentafterlink p{margin:.5em 0}.editing .section .activity:hover,.editing .section .activity.action-menu-shown{background-color:#eee}.course-content .current{background-color:#d9edf7}.course-content .section-summary{margin-top:5px;list-style:none;border:1px solid #DDD}.course-content .section-summary .section-title{margin:2px 5px 10px 5px}.course-content .section-summary .summarytext{margin:2px 5px 2px 5px}.course-content .section-summary .section-summary-activities .activity-count{display:inline-block;margin:3px;font-size:11.9px;color:#999;white-space:nowrap}.course-content .section-summary .summary{margin-top:5px}.course-content .single-section{margin-top:1em}.course-content .single-section .section-navigation{display:block;padding:.5em;margin-bottom:-0.5em}.course-content .single-section .section-navigation .title{clear:both;font-size:108%;font-weight:bold}.course-content .single-section .section-navigation .mdl-left{float:left;margin-right:1em;font-weight:normal}.dir-rtl .course-content .single-section .section-navigation .mdl-left{float:right}.course-content .single-section .section-navigation .mdl-left .larrow{margin-right:.1em}.course-content .single-section .section-navigation .mdl-right{float:right;margin-left:1em;font-weight:normal}.dir-rtl .course-content .single-section .section-navigation .mdl-right{float:left}.course-content .single-section .section-navigation .mdl-right .rarrow{margin-left:.1em}.course-content .single-section .section-navigation .mdl-bottom{margin-top:0}.course-content ul li.section.main{margin-top:0;border-bottom:2px solid #eee}.course-content ul li.section.hidden{opacity:.5}.course-content ul.topics li.section .content,.course-content ul.weeks li.section .content{padding:0;margin-right:20px;margin-left:20px}.course-content{margin-top:0}.course-content ul.topics li.section{padding-bottom:20px}.course-content ul.topics li.section .summary{margin-left:25px}.path-course-view .completionprogress{margin-left:25px}.path-course-view .completionprogress{position:relative;z-index:1000;display:block;float:right;height:20px}#page-site-index .subscribelink{text-align:right}#page-site-index .headingblock{margin-bottom:9px}.path-course-view a.reduce-sections{padding-left:.2em}.path-course-view .headingblock{margin-bottom:9px}.path-course-view .subscribelink{text-align:right}.path-course-view .unread{margin-left:30px}.dir-rtl.path-course-view .unread{margin-right:30px}.path-course-view .block.drag .header{cursor:move}.path-course-view .completionprogress{text-align:right}.dir-rtl.path-course-view .completionprogress{text-align:left}.path-course-view .single-section .completionprogress{margin-right:5px}.path-course-view .section .summary{line-height:normal}.path-site li.activity>div,.path-course-view li.activity>div{position:relative}.path-course-view li.activity span.autocompletion,.path-course-view li.activity form.togglecompletion{float:right}.path-course-view li.activity form.togglecompletion .ajaxworking{width:16px;height:16px;background:url([[pix:i/ajaxloader]]) no-repeat}.dir-rtl.path-course-view li.activity form.togglecompletion,.dir-rtl.path-course-view li.activity span.autocompletion{float:left}.dir-rtl.path-course-view .completionprogress{float:none}.dir-rtl.path-course-view li.activity form.togglecompletion .ajaxworking{right:-22px}li.section.hidden span.commands a.editing_hide,li.section.hidden span.commands a.editing_show{cursor:default}ul.weeks h3.sectionname{white-space:nowrap}.editing ul.weeks h3.sectionname{white-space:normal}.section img.movetarget{width:80px;height:16px}input.titleeditor{width:330px;vertical-align:text-bottom}span.editinstructions{position:absolute;top:0;left:0;z-index:9999;padding:.1em .4em;margin-top:-22px;margin-left:30px;font-size:11.9px;line-height:16px;color:#3a87ad;text-decoration:none;background-color:#d9edf7;border:1px solid #bce8f1;-webkit-box-shadow:2px 2px 5px 1px #ccc;-moz-box-shadow:2px 2px 5px 1px #ccc;box-shadow:2px 2px 5px 1px #ccc}.dir-rtl span.editinstructions{right:32px;left:auto}#dndupload-status{position:absolute;z-index:9999;z-index:0;width:40%;padding:6px;margin:0 30%;color:#3a87ad;text-align:center;background:#d9edf7;border:1px solid #bce8f1;-webkit-border-bottom-right-radius:8px;border-bottom-right-radius:8px;-webkit-border-bottom-left-radius:8px;border-bottom-left-radius:8px;-moz-border-radius-bottomright:8px;-moz-border-radius-bottomleft:8px;-webkit-box-shadow:2px 2px 5px 1px #ccc;-moz-box-shadow:2px 2px 5px 1px #ccc;box-shadow:2px 2px 5px 1px #ccc}.dndupload-preview{padding:.3em;margin-top:.2em;color:#909090;list-style:none;border:1px dashed #909090}.dndupload-preview img.icon{padding:0;vertical-align:text-bottom}.dndupload-progress-outer{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.dndupload-progress-inner{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.dndupload-hidden{display:none}#page-course-pending .singlebutton,#page-course-index .singlebutton,#page-course-index-category .singlebutton,#page-course-editsection .singlebutton{text-align:center}#page-admin-course-manage #movecourses td img{margin:0 .22em;vertical-align:text-bottom}#page-admin-course-manage #movecourses td img.icon{padding:0}#coursesearch{margin-top:1em;text-align:center}#page-course-pending .pendingcourserequests{margin-bottom:1em}#page-course-pending .pendingcourserequests .singlebutton{display:inline}#page-course-pending .pendingcourserequests .cell{padding:0 5px}#page-course-pending .pendingcourserequests .cell.c6{white-space:nowrap}.coursebox{padding:5px;margin-bottom:15px;border:1px dotted #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.coursebox>.info>.name a{display:block;padding-left:21px;background-image:url([[pix:moodle|i/course]]);background-position:center left;background-repeat:no-repeat}.coursebox.remotehost>.info>.name a{background-image:url([[pix:moodle|i/mnethost]])}.coursebox>.info>.name,.coursebox .content .teachers,.coursebox .content .courseimage,.coursebox .content .coursefile{float:left;width:40%;clear:left}.coursebox>.info>h3.name{margin:5px}.coursebox>.info>.name{padding:0;margin:5px}.coursebox .content .teachers li{padding:0;margin:0;list-style-type:none}.coursebox .enrolmenticons{float:right;padding:3px 0}.coursebox .moreinfo{float:right;padding:3px 0}.coursebox .enrolmenticons img,.coursebox .moreinfo img{margin:0 .2em}.coursebox .content{clear:both}.coursebox .content .summary,.coursebox .content .coursecat{float:right;width:55%}.coursebox .content .coursecat{clear:right;text-align:right}.coursebox.remotecoursebox .remotecourseinfo{float:left;width:40%}.coursebox .content .courseimage img{max-width:100px;max-height:100px}.coursebox .content .coursecat,.coursebox .content .summary,.coursebox .content .courseimage,.coursebox .content .coursefile,.coursebox .content .teachers,.coursebox.remotecoursebox .remotecourseinfo{padding:0;margin:3px 5px}.dir-rtl .coursebox>.info>.name a{padding-right:21px;padding-left:0;background-position:center right}.dir-rtl .coursebox>.info>.name,.dir-rtl .coursebox .teachers,.dir-rtl .coursebox .content .courseimage,.dir-rtl .coursebox .content .coursefile{float:right;clear:right}.dir-rtl .coursebox .enrolmenticons,.dir-rtl .coursebox .moreinfo{float:left}.dir-rtl .coursebox .summary,.dir-rtl .coursebox .coursecat{float:left}.dir-rtl .coursebox .coursecat{clear:left;text-align:left}.coursebox.collapsed{margin-bottom:0}.coursebox.collapsed>.content{display:none}.courses .coursebox.collapsed{padding:3px 0;border:1px solid #eee}.courses .coursebox.even{background-color:#f6f6f6}.courses .coursebox:hover,.course_category_tree .courses>.paging.paging-morelink:hover{background-color:#eee}.course_category_tree .category .numberofcourse{font-size:11.9px}.course_category_tree .controls{visibility:hidden}.course_category_tree .controls div{display:inline;cursor:pointer}.jsenabled .course_category_tree .controls{visibility:visible}.course_category_tree .controls{float:right;margin-bottom:5px;text-align:right}.course_category_tree .controls div{padding-right:2em;font-size:75%}.course_category_tree .category>.info .name{padding:2px 18px;margin:3px;background-image:url([[pix:moodle|t/collapsed_empty]]);background-position:center left;background-repeat:no-repeat}.dir-rtl .course_category_tree .category>.info .name{background-image:url([[pix:moodle|t/collapsed_empty_rtl]]);background-position:center right}.course_category_tree .category.with_children>.info .name{background-image:url([[pix:moodle|t/expanded]])}.course_category_tree .category.with_children.collapsed>.info .name{background-image:url([[pix:moodle|t/collapsed]])}.dir-rtl .course_category_tree .category.with_children.collapsed>.info .name{background-image:url([[pix:moodle|t/collapsed_rtl]])}.course_category_tree .category.collapsed>.content{display:none}.course_category_tree .category>.info{min-height:20px;min-height:0;padding:19px;padding:0;margin:3px 0;margin-bottom:20px;margin-bottom:3px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.course_category_tree .category>.info blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.course_category_tree.frontpage-category-names .category>.info{margin:0;background:0;border:0}.course_category_tree .category>.content{padding-left:16px}.dir-rtl .course_category_tree .category>.content{padding-right:16px;padding-left:0}.course_category_tree .subcategories>.paging,.courses>.paging{padding:5px;margin:0;text-align:center}.courses>.paging.paging-morelink,.course_category_tree .subcategories>.paging.paging-morelink{text-align:left}.course_category_tree .paging.paging-morelink a{font-size:11.9px}.dir-rtl .courses>.paging.paging-morelink,.dir-rtl .course_category_tree .paging.paging-morelink{text-align:right}#page-course-index-category .generalbox.info{padding:5px;margin-bottom:15px;border:1px dotted #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}#page-course-index-category .categorypicker{margin:10px 0 20px;text-align:center}.section .activity .moodle-actionmenu .iconsmall{width:16px;width:1rem;height:16px;height:1rem;max-width:none!important;padding:.3em}.filemanager,.filepicker,.file-picker{font-size:11px}.filemanager a,.file-picker a,.filemanager a:hover,.file-picker a:hover{color:#555;text-decoration:none}.filemanager input[type="text"],.file-picker input[type="text"]{width:265px}.filemanager .fp-license td,.file-picker .fp-setlicense td{max-width:265px}.filemanager .fp-license select,.file-picker .fp-setlicense select{max-width:100%}.fp-content-center{display:table-cell;width:100%;height:100%;vertical-align:middle}.fp-content-hidden{visibility:hidden}.yui3-panel-focused{outline:0}#filesskin .yui3-panel-content{display:inline-block;*display:inline;padding-bottom:20px;background:#f2f2f2;border:1px solid #fff;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;*zoom:1;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}#filesskin .yui3-widget-hd{padding:5px;font-size:12px;letter-spacing:1px;color:#333;text-align:center;text-shadow:1px 1px 1px #fff;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border-bottom:1px solid #bbb;-webkit-border-radius:10px 10px 0 0;-moz-border-radius:10px 10px 0 0;border-radius:10px 10px 0 0;filter:dropshadow(color=#ffffff,offx=1,offy=1);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0)}.fp-panel-button{display:inline-block;*display:inline;padding:3px 20px 2px 20px;margin:10px;text-align:center;background:#fff;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;*zoom:1;-webkit-box-shadow:2px 2px 3px .1px #999;-moz-box-shadow:2px 2px 3px .1px #999;box-shadow:2px 2px 3px .1px #999}.filepicker .moodle-dialogue-wrap .moodle-dialogue-bd{padding:0}#filesskin .file-picker.fp-generallayout{position:relative;width:859px;background:#fff;border:1px solid #ccc;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.file-picker .fp-repo-area{display:inline-block;*display:inline;float:left;width:180px;height:525px;overflow:auto;border-right:1px solid #bbb;*zoom:1}.dir-rtl .file-picker .fp-repo-area{float:right;border-right:0;border-left:1px solid #bbb}.file-picker .fp-repo-items{float:left;width:693px}.dir-rtl .file-picker .fp-repo-items{float:right}.file-picker .fp-navbar{min-height:22px;padding:5px 8px;background:#f2f2f2;border-bottom:1px solid #bbb}.file-picker .fp-content{height:468px;overflow:auto;clear:both;background:#fff}.filepicker.moodle-dialogue-fullscreen .file-picker .fp-content{width:100%;height:100%}.dir-rtl .file-picker .fp-repo-items{margin-right:181px}.file-picker .fp-content-loading{display:table;width:100%;height:100%;text-align:center}.file-picker .fp-content .fp-object-container{width:98%;height:98%}.dir-rtl .file-picker .fp-list{text-align:right}.dir-rtl .file-picker .fp-toolbar{padding:0}.dir-rtl .file-picker .fp-list{text-align:right}.dir-rtl .file-picker .fp-repo-name{display:inline}.dir-rtl .file-picker .fp-pathbar{display:block;text-align:right;border-top:0}.dir-rtl .file-picker div.bd{text-align:right}.dir-rtl #filemenu .yuimenuitemlabel{text-align:right}.dir-rtl .filepicker .yui-layout-unit-left{left:500px}.dir-rtl .filepicker .yui-layout-unit-center{left:0}.dir-rtl .filemanager-toolbar a{padding:0}.file-picker .fp-list{float:left;width:100%;padding:0;margin:0;list-style-type:none}.dir-rtl .file-picker .fp-list{float:left;text-align:right}.file-picker .fp-list .fp-repo a{display:block;padding:.5em .7em}.file-picker .fp-list .fp-repo.active{background:#f2f2f2}.file-picker .fp-list .fp-repo-icon{padding:0 7px 0 5px}.fp-toolbar{display:table-row;float:left;max-width:70%;line-height:22px}.dir-rtl .fp-toolbar{float:right}.fp-toolbar.empty{display:none}.fp-toolbar .disabled{display:none}.fp-toolbar div{display:inline-block;*display:inline;padding:0 2px;padding-right:10px;*zoom:1}.dir-rtl .fp-toolbar div{width:100px;padding-right:0}.fp-toolbar img{margin-right:5px;vertical-align:-15%}.fp-toolbar .fp-tb-search{width:228px;height:14px}.fp-toolbar .fp-tb-search input{width:200px;height:16px;padding:2px 6px 1px 20px;background:#fff url('[[pix:a/search]]') no-repeat 3px 3px;border:1px solid #bbb}.fp-viewbar{float:right;width:69px;height:22px;margin-right:8px}.dir-rtl .fp-toolbar img{vertical-align:-35%}.dir-rtl .fp-viewbar{float:left;width:100px}.fp-vb-icons{display:inline-block;*display:inline;width:22px;height:22px;background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-icons{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0}.fp-vb-icons.checked{background:url('[[pix:theme|fp/view_icon_selected]]')}.dir-rtl .fp-vb-icons.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_icon_selected]]')}.fp-viewbar.disabled .fp-vb-icons{background:url('[[pix:theme|fp/view_icon_inactive]]')}.fp-vb-details{display:inline-block;*display:inline;width:23px;height:22px;margin-left:-4px;background:url('[[pix:theme|fp/view_list_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-details{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_list_active]]') no-repeat 0 0}.fp-vb-details.checked{background:url('[[pix:theme|fp/view_list_selected]]')}.dir-rtl .fp-vb-details.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_list_selected]]')}.fp-viewbar.disabled .fp-vb-details{background:url('[[pix:theme|fp/view_list_inactive]]')}.fp-vb-tree{display:inline-block;*display:inline;width:23px;height:22px;margin-left:-4px;background:url('[[pix:theme|fp/view_tree_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-tree{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_tree_active]]') no-repeat 0 0}.fp-vb-tree.checked{background:url('[[pix:theme|fp/view_tree_selected]]')}.dir-rtl .fp-vb-tree.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_tree_selected]]')}.fp-viewbar.disabled .fp-vb-tree{background:url('[[pix:theme|fp/view_tree_inactive]]')}.file-picker .fp-clear-left{clear:left}.dir-rtl .filemanager-toolbar .fp-vb-icons a:hover{background:url('[[pix:theme|fp/view_icon_selected]]')}.dir-rtl .filemanager-toolbar .fp-vb-icons.checked a:hover{background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0}.dir-rtl .fp-vb-details a:hover{background:0;border:20px solid black}.dir-rtl .fp-vb-details.checked a:hover{background:0;border:40px solid black}.dir-rtl .fp-vb-tree a:hover{background:0;border:30px solid black}.dir-rtl .fp-vb-tree.checked a:hover{background:0;border:50px solid black}.file-picker .fp-pathbar{display:table-row}.fp-pathbar.empty{display:none}.fp-pathbar .fp-path-folder{width:27px;height:12px;margin-left:4px;background:url('[[pix:theme|fp/path_folder]]') no-repeat 0 0}.dir-rtl .fp-pathbar .fp-path-folder{width:auto;height:12px;margin-left:4px;background:url('[[pix:theme|fp/path_folder_rtl]]') no-repeat right top}.dir-rtl .fp-pathbar span{display:inline-block;*display:inline;float:right;margin-left:32px;*zoom:1}.fp-pathbar .fp-path-folder-name{margin-left:32px;line-height:20px}.dir-rtl .fp-pathbar .fp-path-folder-name{margin-right:32px;line-height:20px}.fp-iconview .fp-file{position:relative;float:left;margin:10px 10px 35px;text-align:center}.fp-iconview .fp-thumbnail{display:block;min-width:110px;min-height:110px;line-height:110px;text-align:center;border:1px solid #fff}.fp-iconview .fp-thumbnail img{padding:3px;vertical-align:middle;border:1px solid #ddd;-webkit-box-shadow:1px 1px 2px 0 #ccc;-moz-box-shadow:1px 1px 2px 0 #ccc;box-shadow:1px 1px 2px 0 #ccc}.fp-iconview .fp-thumbnail:hover{background:#fff;border:1px solid #ddd;-webkit-box-shadow:inset 0 0 10px 0 #ccc;-moz-box-shadow:inset 0 0 10px 0 #ccc;box-shadow:inset 0 0 10px 0 #ccc}.fp-iconview .fp-filename-field{position:absolute;height:33px;overflow:hidden;word-wrap:break-word}.fp-iconview .fp-filename-field:hover{z-index:1000;overflow:visible}.fp-iconview .fp-filename-field .fp-filename{min-width:112px;padding-top:5px;padding-bottom:12px;background:#fff}.dir-rtl .fp-iconview .fp-file{float:right}.file-picker .yui3-datatable table{width:100%;border:0 solid #bbb}#filesskin .file-picker .yui3-datatable-header{color:#555;background:#fff;border-bottom:1px solid #ccc;border-left:0 solid #fff}#filesskin .file-picker .yui3-datatable-odd .yui3-datatable-cell{background-color:#f6f6f6;border-left:0 solid #f6f6f6}#filesskin .file-picker .yui3-datatable-even .yui3-datatable-cell{background-color:#fff;border-left:0 solid #fff}.dir-rtl .file-picker .yui3-datatable-header{text-align:right}.file-picker .ygtvtn,.filemanager .ygtvtn{width:17px;height:22px;background:url('[[pix:moodle|y/tn]]') 0 0 no-repeat}.dir-rtl .filemanager .ygtvtn,.dir-rtl .file-picker .ygtvtn{width:17px;height:22px;background:url('[[pix:moodle|y/tn_rtl]]') 0 0 no-repeat}.file-picker .ygtvtm,.filemanager .ygtvtm{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tm]]') 0 10px no-repeat}.file-picker .ygtvtmh,.filemanager .ygtvtmh{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tm]]') 0 10px no-repeat}.file-picker .ygtvtp,.filemanager .ygtvtp{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvtp,.dir-rtl .filemanager .ygtvtp{background:url('[[pix:moodle|y/tp_rtl]]') 0 10px no-repeat}.file-picker .ygtvtph,.filemanager .ygtvtph{width:13px;height:22px;cursor:pointer;background:url('[[pix:moodle|y/tp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvtph,.dir-rtl .filemanager .ygtvtph{background:url('[[pix:moodle|y/tp_rtl]]') 0 10px no-repeat}.file-picker .ygtvln,.filemanager .ygtvln{width:17px;height:22px;background:url('[[pix:moodle|y/ln]]') 0 0 no-repeat}.dir-rtl .file-picker .ygtvln,.dir-rtl .filemanager .ygtvln{background:url('[[pix:moodle|y/ln_rtl]]') 0 0 no-repeat}.file-picker .ygtvlm,.filemanager .ygtvlm{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lm]]') 0 10px no-repeat}.file-picker .ygtvlmh,.filemanager .ygtvlmh{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lm]]') 0 10px no-repeat}.file-picker .ygtvlp,.filemanager .ygtvlp{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvlp,.dir-rtl .filemanager .ygtvlp{background:url('[[pix:moodle|y/lp_rtl]]') 0 10px no-repeat}.file-picker .ygtvlph,.filemanager .ygtvlph{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvlph,.dir-rtl .filemanager .ygtvlph{background:url('[[pix:moodle|y/lp_rtl]]') 0 10px no-repeat}.file-picker .ygtvloading,.filemanager .ygtvloading{width:16px;height:22px;background:transparent url('[[pix:moodle|y/loading]]') 0 0 no-repeat}.file-picker .ygtvdepthcell,.filemanager .ygtvdepthcell{width:17px;height:32px;background:url('[[pix:moodle|y/vline]]') 0 0 no-repeat}.file-picker .ygtvblankdepthcell,.filemanager .ygtvblankdepthcell{width:17px;height:22px}a.ygtvspacer:hover{color:transparent;text-decoration:none}.ygtvlabel,.ygtvlabel:link,.ygtvlabel:visited,.ygtvlabel:hover{margin-left:2px;text-decoration:none;cursor:pointer;background-color:transparent}.file-picker .ygtvfocus,.filemanager .ygtvfocus{background-color:#eee}.fp-filename-icon{position:relative;display:block;margin-top:10px}.fp-icon{float:left;width:24px;height:24px;margin-top:-7px;margin-right:10px;line-height:24px;text-align:center}.dir-rtl .fp-icon{float:right;margin-right:0;margin-left:10px}.fp-icon img{max-width:24px;max-height:24px;vertical-align:middle}.fp-filename{padding-right:10px}.dir-rtl .fp-filename{padding-right:0;padding-left:10px}.file-picker .fp-login-form{display:table;width:100%;height:100%}.file-picker .fp-login-form table{margin:0 auto}.file-picker .fp-login-form p{margin-top:3em;text-align:center}.file-picker .fp-login-form .fp-login-input label{display:block;text-align:right}.file-picker .fp-login-form .fp-login-input .input{text-align:left}.file-picker .fp-login-form input[type="checkbox"]{width:15px;height:15px}.file-picker .fp-upload-form{display:table;width:100%;height:100%}.file-picker .fp-upload-form table{margin:0 auto}.file-picker.fp-dlg{text-align:center}.file-picker.fp-dlg .fp-dlg-text{padding:30px 20px 10px;font-size:12px}.file-picker.fp-dlg .fp-dlg-buttons{margin:0 20px}.file-picker.fp-msg{text-align:center}.file-picker.fp-msg .fp-msg-text{max-width:500px;max-height:300px;min-width:200px;padding:40px 20px 10px 20px;overflow:auto;font-size:12px}.file-picker.fp-msg.fp-msg-error .fp-msg-text{padding:40px 20px 10px 20px;font-size:12px}.file-picker .fp-content-error{display:table;width:100%;height:100%;text-align:center}.file-picker .fp-content-error .fp-error{display:table-cell;width:100%;height:100%;padding:40px 20px 10px 20px;font-size:12px;vertical-align:middle}.file-picker .fp-nextpage{clear:both}.file-picker .fp-nextpage .fp-nextpage-loading{display:none}.file-picker .fp-nextpage.loading .fp-nextpage-link{display:none}.file-picker .fp-nextpage.loading .fp-nextpage-loading{display:block;height:100px;padding-top:50px;text-align:center}.fp-select form{padding:20px 20px 0}.fp-select .fp-select-loading{margin-top:20px;text-align:center}.fp-select .fp-hr{width:auto;height:1px;margin:10px 0;clear:both;background-color:#fff;border-bottom:1px solid #bbb}.fp-select table{padding:0 0 10px}.fp-select table .mdl-right{min-width:84px}.fp-select .fp-reflist .mdl-right{vertical-align:top}.fp-select .fp-select-buttons{float:right}.fp-select .fp-info{display:block;padding:1px 20px 0;clear:both}.fp-select .fp-thumbnail{float:left;min-width:110px;min-height:110px;margin:10px 20px 0 0;line-height:110px;text-align:center;background:#fff;border:1px solid #ddd;-webkit-box-shadow:inset 0 0 10px 0 #ccc;-moz-box-shadow:inset 0 0 10px 0 #ccc;box-shadow:inset 0 0 10px 0 #ccc}.fp-select .fp-thumbnail img{padding:3px;margin:10px;vertical-align:middle;border:1px solid #ddd}.fp-select .fp-fileinfo{display:inline-block;*display:inline;margin-top:10px;*zoom:1}.file-picker.fp-select .fp-fileinfo{max-width:240px}.fp-select .fp-fileinfo div{padding-bottom:5px}.file-picker.fp-select .uneditable{display:none}.file-picker.fp-select .fp-select-loading{display:none}.file-picker.fp-select.loading .fp-select-loading{display:block}.file-picker.fp-select.loading form{display:none}.fp-select .fp-dimensions.fp-unknown{display:none}.filemanager-loading{display:none}.jsenabled .filemanager-loading{display:block;margin-top:100px}.filemanager.fm-loading .filemanager-toolbar,.filemanager.fm-loading .fp-pathbar,.filemanager.fm-loading .filemanager-container,.filemanager.fm-loaded .filemanager-loading,.filemanager.fm-maxfiles .fp-btn-add,.filemanager.fm-maxfiles .dndupload-message,.filemanager.fm-noitems .fp-btn-download,.filemanager .fm-empty-container,.filemanager.fm-noitems .filemanager-container .fp-content{display:none}.filemanager .filemanager-updating{display:none;text-align:center}.filemanager.fm-updating .filemanager-updating{display:block;margin-top:37px}.filemanager.fm-updating .fm-content-wrapper,.filemanager.fm-nomkdir .fp-btn-mkdir,.fitem.disabled .filemanager .filemanager-toolbar,.fitem.disabled .filemanager .fp-pathbar,.fitem.disabled .filemanager .fp-restrictions,.fitem.disabled .filemanager .fm-content-wrapper{display:none}.fp-restrictions{text-align:right}.filemanager .fp-navbar{background:#f2f2f2;border:1px solid #bbb;border-bottom:0}.filemanager-toolbar{min-height:22px;padding:5px 8px;overflow:hidden}.fp-pathbar{min-height:20px;padding:5px 8px 1px;border-top:1px solid #bbb}.filemanager .fp-pathbar.empty{display:none}.filepicker-filelist,.filemanager-container{position:relative;min-height:140px;overflow:auto;clear:both;background:#fff;border:1px solid #bbb}.filemanager .fp-content{max-height:472px;min-height:157px;overflow:auto}.filemanager-container,.filepicker-filelist{overflow:hidden}.fitem.disabled .filepicker-filelist,.fitem.disabled .filemanager-container{background-color:#ebebe4}.fitem.disabled .fp-btn-choose{color:#999}.fitem.disabled .filepicker-filelist .filepicker-filename{display:none}.fp-iconview .fp-reficons1{position:absolute;top:0;left:0;z-index:1000;width:100%;height:100%}.fp-iconview .fp-reficons2{position:absolute;top:0;left:0;z-index:1001;width:100%;height:100%}.fp-iconview .fp-file.fp-hasreferences .fp-reficons1{background:url('[[pix:theme|fp/link]]') no-repeat;background-position:bottom right}.fp-iconview .fp-file.fp-isreference .fp-reficons2{background:url('[[pix:theme|fp/alias]]') no-repeat;background-position:bottom left}.filemanager .fp-iconview .fp-file.fp-originalmissing .fp-thumbnail img{display:none}.filemanager .fp-iconview .fp-file.fp-originalmissing .fp-thumbnail{background:url([[pix:s/dead]]) no-repeat;background-position:center center}.filemanager .yui3-datatable table{width:100%;border:0 solid #bbb}.filemanager .yui3-datatable-header{color:#555!important;background:#fff!important;border-bottom:1px solid #ccc!important;border-left:0 solid #fff!important}.filemanager .yui3-datatable-odd .yui3-datatable-cell{background-color:#f6f6f6!important;border-left:0 solid #f6f6f6}.filemanager .yui3-datatable-even .yui3-datatable-cell{background-color:#fff!important;border-left:0 solid #fff}.filemanager .fp-filename-icon.fp-hasreferences .fp-reficons1{position:absolute;top:8px;left:17px;z-index:1000;width:100%;height:100%;background:url('[[pix:theme|fp/link_sm]]') no-repeat 0 0}.filemanager .fp-filename-icon.fp-isreference .fp-reficons2{position:absolute;top:9px;left:-6px;z-index:1001;width:100%;height:100%;background:url('[[pix:theme|fp/alias_sm]]') no-repeat 0 0}.filemanager .fp-contextmenu{display:none}.filemanager .fp-iconview .fp-folder.fp-hascontextmenu .fp-contextmenu{position:absolute;right:7px;bottom:5px;display:block}.filemanager .fp-treeview .fp-folder.fp-hascontextmenu .fp-contextmenu,.filemanager .fp-tableview .fp-folder.fp-hascontextmenu .fp-contextmenu{position:absolute;top:6px;left:14px;display:inline;margin-right:-20px}.dir-rtl .filemanager .fp-iconview .fp-folder.fp-hascontextmenu .fp-contextmenu{right:inherit;left:7px}.dir-rtl .filemanager .fp-treeview .fp-folder.fp-hascontextmenu .fp-contextmenu,.dir-rtl .filemanager .fp-tableview .fp-folder.fp-hascontextmenu .fp-contextmenu{right:16px;left:inherit;margin-right:0}.filepicker-filelist .filepicker-container,.filemanager.fm-noitems .fm-empty-container{position:absolute;top:10px;right:10px;bottom:10px;left:10px;display:block;padding-top:85px;text-align:center;border:2px dashed #bbb}.filepicker-filelist .dndupload-target,.filemanager-container .dndupload-target{position:absolute;top:10px;right:10px;bottom:10px;left:10px;padding-top:85px;text-align:center;background:#fff;border:2px dashed #fb7979;-webkit-box-shadow:0 0 0 10px #fff;-moz-box-shadow:0 0 0 10px #fff;box-shadow:0 0 0 10px #fff}.filepicker-filelist.dndupload-over .dndupload-target,.filemanager-container.dndupload-over .dndupload-target{position:absolute;top:10px;right:10px;bottom:10px;left:10px;padding-top:85px;text-align:center;background:#fff;border:2px dashed #6c8cd3}.dndupload-message{display:none}.dndsupported .dndupload-message{display:inline}.dnduploadnotsupported-message{display:none}.dndnotsupported .dnduploadnotsupported-message{display:inline}.dndupload-target{display:none}.dndsupported .dndupload-ready .dndupload-target{display:block}.dndupload-uploadinprogress{display:none;text-align:center}.dndupload-uploading .dndupload-uploadinprogress{display:block}.dndupload-arrow{position:absolute;top:5px;width:100%;height:80px;margin-left:-28px;background:url([[pix:theme|fp/dnd_arrow]]) center no-repeat}.fitem.disabled .filepicker-container,.fitem.disabled .fm-empty-container{display:none}.dndupload-progressbars{display:none;padding:10px}.dndupload-inprogress .dndupload-progressbars{display:block}.dndupload-inprogress .fp-content{display:none}.filemanager.fm-noitems .dndupload-inprogress .fm-empty-container{display:none}.filepicker-filelist.dndupload-inprogress .filepicker-container{display:none}.filepicker-filelist.dndupload-inprogress a{display:none}.filemanager.fp-select .fp-select-loading{display:none}.filemanager.fp-select.loading .fp-select-loading{display:block}.filemanager.fp-select.loading form{display:none}.filemanager.fp-select.fp-folder .fp-license,.filemanager.fp-select.fp-folder .fp-author,.filemanager.fp-select.fp-file .fp-file-unzip,.filemanager.fp-select.fp-folder .fp-file-unzip,.filemanager.fp-select.fp-file .fp-file-zip,.filemanager.fp-select.fp-zip .fp-file-zip{display:none}.filemanager.fp-select .fp-file-setmain{display:none}.filemanager.fp-select.fp-cansetmain .fp-file-setmain{display:inline-block;*display:inline;*zoom:1}.filemanager .fp-mainfile .fp-filename{font-weight:bold}.filemanager.fp-select.fp-folder .fp-file-download{display:none}.fm-operation{font-weight:bold}.filemanager.fp-select .fp-original.fp-unknown,.filemanager.fp-select .fp-original .fp-originloading{display:none}.filemanager.fp-select .fp-original.fp-loading .fp-originloading{display:inline}.filemanager.fp-select .fp-reflist.fp-unknown,.filemanager.fp-select .fp-reflist .fp-reflistloading{display:none}.filemanager.fp-select .fp-refcount{max-width:265px}.filemanager.fp-select .fp-reflist.fp-loading .fp-reflistloading{display:inline}.filemanager.fp-select .fp-reflist .fp-value{max-width:265px;max-height:75px;padding:8px 7px;margin:0;overflow:auto;background:#f9f9f9;border:1px solid #bbb}.filemanager.fp-select .fp-reflist .fp-value li{padding-bottom:7px}.filemanager.fp-mkdir-dlg{text-align:center}.filemanager.fp-mkdir-dlg .fp-mkdir-dlg-text{margin:20px;text-align:left}.dir-rtl .filemanager .fp-mkdir-dlg p{text-align:right}.filemanager.fp-dlg{text-align:center}.filemanager.fp-dlg .fp-dlg-text{max-width:340px;max-height:300px;min-width:200px;padding:0 10px;margin:40px 20px 20px;overflow:auto;font-size:12px;line-height:22px}.file-picker div.bd{text-align:left}.dir-rtl .file-picker div.bd,.dir-rtl .file-picker .fp-pathbar,.dir-rtl .file-picker .fp-list,.dir-rtl #filemenu .yuimenuitemlabel,.dir-rtl .filemanager-container .yui3-skin-sam .yui3-datatable-header{text-align:right}.dir-rtl .filepicker .yui-layout-unit-left{left:500px}.dir-rtl .filepicker .yui-layout-unit-center{left:0}.allcoursegrades{width:100%;padding:4px 0 5px 0;text-align:right}.path-grade-edit .buttons{text-align:center}.path-grade-edit-tree .idnumber{margin-left:15px}.path-grade-edit-tree .movetarget{position:relative;width:80px;height:16px}.path-grade-edit-tree ul#grade_tree{width:auto}.path-grade-edit-tree ul#grade_tree li{list-style:none}.path-grade-edit-tree ul#grade_tree li.category{margin-bottom:6px}.path-grade-edit-tree .iconsmall{margin-left:4px}#grade-report-toggles{text-align:center}#grade-aggregation-help dt{margin-top:15px}#grade-aggregation-help dd.example{margin-top:7px}#grade-aggregation-help code{display:block;margin-top:7px}.gradeexportlink{padding:2em;text-align:center}.gradetreebox{margin-top:10px;overflow-x:auto;overflow-y:hidden}.gradetreebox table{width:100%;font-size:.8em}.gradetreebox td.colspan,.gradetreebox tr.category .cell{background-color:#DDD}.gradetreebox th.actions{width:105px;white-space:nowrap}.gradetreebox td.name{white-space:nowrap}.gradetreebox td.name h4{display:inline}.gradetreebox td.range{white-space:nowrap}.gradetreebox span.actionlink{color:blue}.gradetreebox span.actionlink:hover{text-decoration:underline;cursor:pointer}.gradetreebox img.iconsmall{margin-left:4px}.gradetreebox img.icon{margin-right:5px}.gradetreebox #gradetreesubmit{margin-bottom:1em;text-align:center}.gradetreebox .hidden{display:none}#page-grade-grading-manage #activemethodselector{margin-bottom:1em;text-align:center}#page-grade-grading-manage #activemethodselector select{margin:0 1em}#page-grade-grading-manage .actions{text-align:center}#page-grade-grading-manage .action{display:inline-block;width:150px;padding:.5em;margin:.5em;text-align:center;background-color:#eee;border:2px solid #ccc;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-manage .action:hover{text-decoration:none;background-color:#f6f6f6}#page-grade-grading-manage #actionresultmessagebox{position:relative;width:60%;padding:.5em;margin:1em auto;text-align:center;background-color:#d2ebff;border:2px solid #CCC;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-manage #actionresultmessagebox span{position:absolute;top:-1.2em;right:0;font-size:80%;color:#666}#page-grade-grading-manage .definition-name .status{padding:.25em;font-size:60%;font-weight:normal;text-transform:uppercase;border:1px solid #EEE;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-manage .definition-name .status.ready{background-color:#e7f1c3;border-color:#aea}#page-grade-grading-manage .definition-name .status.draft{background-color:#f3f2aa;border-color:#ee2}#page-grade-grading-manage .definition-preview{width:50%;padding:1em;margin:1em auto;border:1px solid #EEE}#page-grade-grading-pick .template-name{padding:3px;clear:both;background-color:#f6f6f6}#page-grade-grading-pick .template-name .type{padding:.25em;font-size:60%;font-weight:normal;text-transform:uppercase;border:1px solid #eee;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-pick .template-name .type.shared{background-color:#e7f1c3;border-color:#aea}#page-grade-grading-pick .template-name .type.ownform{background-color:#d2ebff;border-color:#ace}#page-grade-grading-pick .template-description{padding:0 2em 0 0;margin-right:51%;margin-bottom:1em}#page-grade-grading-pick .template-preview{float:right;width:50%;padding:1em;margin-bottom:1em;border:1px solid #EEE}#page-grade-grading-pick .template-actions{padding:0 2em 0 0;margin-right:51%;margin-bottom:1em}#page-grade-grading-pick .template-actions .action{display:inline-block;padding:.25em;margin:.25em;border:2px solid transparent}#page-grade-grading-pick .template-actions .action.pick{background-color:#EEE;border:2px solid #CCC;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}#page-grade-grading-pick .template-actions .action:hover{text-decoration:none;background-color:#f6f6f6;border:2px solid #CCC;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}#page-grade-grading-pick .template-actions .action .action-text{display:inline}#page-grade-grading-pick .template-actions .action .action-icon{margin:0 3px}#page-grade-grading-pick .template-preview-confirm{width:50%;padding:1em;margin:1em auto;border:1px solid #EEE}#page-grade-grading-pick .singlebutton{clear:both}table#user-grades tr.avg td.cell{font-weight:700;color:#00008b;background-color:#efefff}table#user-grades tr td.overridden{background-color:#f3e4c0}table#user-grades tr.odd td.overridden{background-color:#efd9a4}table#user-grades tr td.ajaxoverridden{background-color:#ffe3a0}table#user-grades tr.odd td.ajaxoverridden{background-color:#ffda83}table#user-grades tr.even td.excluded{background-color:#eabfff}table#user-grades tr.odd td.excluded{background-color:#e5afff}table#user-grades tr.groupavg td.cell{font-weight:700;color:#006400;background-color:#efffef}table#user-grades td.cat,table#user-grades td.course{font-weight:700}.path-grade-report-grader #overDiv table{margin:0}.path-grade-report-grader #overDiv table td.feedback{border:0}.path-grade-report-grader #overDiv .feedback{font-size:10.5px;font-weight:400;background-color:#ABF}.path-grade-report-grader #overDiv .caption{font-size:10.5px;font-weight:700;color:#CCF;background-color:#56C}.path-grade-report-grader #overDiv .intersection{font-size:10.5px;font-weight:400;color:#000;background-color:#ABF}.path-grade-report-grader #overDiv .intersectioncaption{font-weight:700;color:#CCF;background-color:#56C}.path-grade-report-grader div.gradeparent,table#user-grades td.ajax{text-align:left}.path-grade-report-grader.dir-rtl div.gradeparent,.dir-rtl table#user-grades td.ajax{text-align:right}table#user-grades td,table#user-grades th{text-align:right}table#user-grades .courseitem{text-align:right;white-space:nowrap}table#user-grades th.category,table#user-grades th#studentheader,table#user-grades th.user{text-align:left}.dir-rtl table#user-grades th.category,.dir-rtl table#user-grades th#studentheader,.dir-rtl table#user-grades th.user{text-align:right}div.gradertoggle{display:inline;margin-left:20px}table#user-grades .userpic{margin-right:10px}table#user-grades .quickfeedback{margin-left:10px;border:1px dashed #000}.dir-rtl table#user-grades .quickfeedback{margin-right:10px;margin-left:0}.path-grade-report-grader #siteconfiglink{text-align:right}table#user-grades .datesubmitted{font-size:10.5px}.path-grade-report-grader span.inclusion-links{margin:0 5px 0 10px}.path-grade-report-grader th.user img.userpicture{margin-right:.5em}.path-grade-report-grader.dir-rtl th.user img.userpicture{margin-left:.5em}.path-grade-report-grader a.quickedit{display:block;float:right;margin:.1em 0 0;clear:none;font-size:9px;line-height:1em;background-color:transparent}.path-grade-report-grader a.quickedit2{display:block;float:right;margin:1.3em 0 0;clear:none;background-color:transparent}.path-grade-report-grader table#quick_edit{margin:0 auto;border:1px solid #cecece}.path-grade-report-grader table#quick_edit td{padding:5px;margin:0;text-align:left;vertical-align:middle;border:1px solid #cecece}.path-grade-report-grader table#quick_edit td img{padding:0;vertical-align:middle;border:3px double #cecece}.path-grade-report-grader table#quick_edit td.fullname{padding-left:5px;border-left:0}.path-grade-report-grader table#quick_edit td.picture{border-right:0}.path-grade-report-grader table#quick_edit td.finalgrade input{width:5em}.path-grade-report-grader h1{clear:both;text-align:center}.path-grade-report-grader input.center{margin:10px auto 0}.path-grade-report-grader .lefttbody{width:auto;vertical-align:middle}.path-grade-report-grader .left_scroller{float:left;clear:none}.path-grade-report-grader .left_scroller #fixed_column .heading th.header,.path-grade-report-grader .left_scroller #fixed_column td,.path-grade-report-grader .left_scroller #fixed_column th{height:4em}.path-grade-report-grader .left_scroller #fixed_column td.controls{height:2em}.path-grade-report-grader.dir-rtl .left_scroller{float:right}.path-grade-report-grader .right_scroller{width:auto;overflow-x:scroll;clear:none}.path-grade-report-grader .right_scroller tr.heading_name_row th,.path-grade-report-grader .right_scroller table#user-grades td.grade{height:4em}.path-grade-report-grader .right_scroller .path-grade-report-grader .left_scroller .topleft,.path-grade-report-grader .right_scroller tr.avg td,.path-grade-report-grader .right_scroller tr.groupavg,.path-grade-report-grader .right_scroller tr.controls_row,.path-grade-report-grader .right_scroller div.right_scroller tr{height:2em}table#fixed_column,table#user-grades,table#fixed_column th,table#fixed_column td,table#user-grades td,table#user-grades th,table#user-grades input{padding:0 2px;margin:0;font-size:10px;vertical-align:middle}.path-grade-report-grader form td.excluded{color:#b94a48}.path-grade-report-grader .excludedfloater{float:left;font-size:9px;font-weight:700;color:#b94a48}.path-grade-report-grader span.gradepass{color:#298721}.path-grade-report-grader span.gradefail{color:#890d0d}.path-grade-report-grader .gradeweight{font-weight:700;color:#461d7c}.path-grade-report-grader td select{padding:0;font-size:100%}.path-grade-report-grader .right_scroller td select{font-size:11.9px}.path-grade-report-grader .grade_icons img.ajax{float:right}.path-grade-report-grader .gradestable th.user,.path-grade-report-grader .gradestable th.range,.path-grade-report-grader .flexible th,.path-grade-report-grader .flexible td,.path-grade-report-grader .flexible th a,.path-grade-report-grader .flexible td a,.path-grade-report-grader .gradestable th.range,.path-grade-report-grader th,.path-grade-report-grader td{white-space:nowrap}table#user-grades td.vmarked{background-color:#fc3}table#user-grades td.hmarked{background-color:#ff9}table#user-grades td.hmarked.vmarked{background-color:#fc9}.path-grade-report-grader .gradeparent{overflow:auto}table#fixed_column tr.controls td,table#user-grades tr.controls td,.path-grade-report-grader table tr.avg,.path-grade-report-grader table tr.avg:hover{background-color:#d9edf7}.path-grade-report-grader table th.user,.path-grade-report-grader table td.userfield{text-align:left}.path-grade-report-grader.dir-rtl table th.user,.path-grade-report-grader.dir-rtl table td.userfield{text-align:right}.path-grade-report-grader .usersuspended a:link,.path-grade-report-grader .usersuspended a:visited{color:#999}.path-grade-report-grader table th.usersuspended img.usersuspendedicon{margin-left:.45em;vertical-align:text-bottom}.path-grade-report-grader .yui3-overlay{left:0;padding:2px 5px;font-size:.7em;background-color:#ffee69;border-color:#d4c237 #a6982b #a6982b;border-style:solid;border-width:1px}.path-grade-report-grader .yui3-overlay .fullname{font-weight:bold;color:#5f3e00}.path-grade-report-grader .yui3-overlay .itemname{font-weight:bold;color:#194f3e}.path-grade-report-grader .yui3-overlay .feedback{color:#5f595e}.path-grade-report-grader #tooltipPanel{text-align:left}.path-grade-report-grader .yui3-overlay a.container-close{margin-top:-3px}.path-grade-report-grader #hiddentooltiproot,.tooltipDiv{display:none}.gradingform_rubric.editor .criteria .definition textarea,.gradingform_rubric.editor .criteria .scorevalue input{width:auto}.gradingform_rubric.editor .criteria .scorevalue input{float:left}.message-discussion-noframes h1{font-size:1em}.message-discussion-noframes #userinfo .commands,.message .noframesjslink,.message .link{font-size:11.9px}.message .heading{font-size:1em;font-weight:bold}.message .author{font-weight:bold}.message .time{font-style:italic}#page-message-user .commands span{font-size:.7em}#page-message-user .name{font-size:1.1em;font-weight:bold}table.message_search_results td{border-color:#ddd}.message .time,.message.me .author{color:#999}.message.other .author{color:#88c}#page-message-messages{padding:10px}#page-message-send .notifysuccess{padding:1px}#page-message-send td.fixeditor{text-align:center}.message .note{padding:10px}table.message .searchresults td{padding:5px}.message .contactselector{float:left;width:24%}.message .contactselector .contact{text-align:left}.message .contactselector .messageselecteduser{font-weight:bold}.message .contactselector .paging{position:relative;z-index:1}.message .messagearea{float:right;width:74%;min-height:200px;padding-left:1%;border-left:1px solid #d3d3d3}.message .messagearea .messagehistorytype{padding-bottom:20px;clear:both}.message .messagearea .messagehistory .message_user_pictures{margin-right:auto;margin-left:auto}.message .messagearea .messagehistory .message_user_pictures #user1{width:200px;vertical-align:top}.message .messagearea .messagehistory .message_user_pictures #user2{width:200px;vertical-align:top}.message .messagearea .messagehistory .message_user_pictures .useractionlinks{font-size:.9em}.message .messagearea .messagehistory .heading{width:100%;clear:both}.message .messagearea .messagehistory .left{float:left;width:50%;padding-bottom:10px;clear:both}.message .messagearea .messagehistory .right{float:right;width:50%;padding-bottom:10px;clear:both}.message .messagearea .messagehistory .notification{padding:10px;margin-top:5px;background-color:#eee}.message .messagearea .messagesend{padding-top:20px;clear:both}.message .messagearea .messagesend .messagesendbox{width:100%}.message .messagearea .messagesend fieldset{padding:0;margin:0}.message .messagearea .messagerecent{width:100%;text-align:left}.message .messagearea .messagerecent .singlemessage{padding:10px;border-bottom:1px solid #d3d3d3}.message .messagearea .messagerecent .singlemessage .otheruser span{padding:5px}.message .messagearea .messagerecent .singlemessage .messagedate{float:right}.message .hiddenelement{display:none}.message .visible{display:inline}.message #usergroupselector.fieldset,.message #viewing{width:100%}.messagesearchresults{margin-bottom:40px}.messagesearchresults td{padding:0 10px 0 20px}.messagesearchresults td span{white-space:nowrap}.messagesearchresults td img.userpicture{padding-right:.45em;vertical-align:text-bottom}.dir-rtl .messagesearchresults td img.userpicture{padding-right:0;padding-left:.45em}.messagesearchresults td span img{padding:0 0 0 .45em;vertical-align:text-bottom}.dir-rtl .messagesearchresults td span img{padding:0 .45em 0 0}#newmessageoverlay{position:fixed;right:0;bottom:0;padding:20px;background-color:#d3d3d3;border:1px solid black}#newmessageoverlay #usermessage{padding:10px}.questionbank h2{margin-top:0}.questioncategories h3{margin-top:0}#chooseqtypebox{margin-top:1em}#chooseqtype h3{margin:0 0 .3em}#chooseqtype .instruction{display:none}#chooseqtype .fakeqtypes{border-top:1px solid silver}#chooseqtype .qtypeoption{margin-bottom:.5em}#chooseqtype label{display:block}#chooseqtype .qtypename img{padding:0 .3em}#chooseqtype .qtypename{display:inline-table;width:16em}#chooseqtype .qtypesummary{display:block;margin:0 2em}#chooseqtype .submitbuttons{margin:.7em 0;text-align:center}#qtypechoicecontainer{display:none}#qtypechoicecontainer_c.yui-panel-container.shadow .underlay{background:0}#qtypechoicecontainer.yui-panel .hd{letter-spacing:1px;color:#333;text-shadow:1px 1px 1px #fff;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border:1px solid #ccc;border-bottom:1px solid #bbb;-webkit-border-top-right-radius:10px;border-top-right-radius:10px;-webkit-border-top-left-radius:10px;border-top-left-radius:10px;-moz-border-radius-topright:10px;-moz-border-radius-topleft:10px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0)}#qtypechoicecontainer{font-size:12px;color:#333;background:#f2f2f2;border:1px solid #ccc;border-top:0 none;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}#chooseqtype{width:40em}#chooseqtypehead h3{margin:0;font-weight:normal}#chooseqtype .qtypes{position:relative;padding:.24em 0;border-bottom:1px solid #bbb}#chooseqtype .qtypeoption{padding:.3em .3em .3em 1.6em;margin-bottom:0}#chooseqtype .qtypeoption img{padding-right:.5em;padding-left:1em;vertical-align:text-bottom}#chooseqtype .selected{background-color:#fff;-webkit-box-shadow:0 0 10px 0 #ccc;-moz-box-shadow:0 0 10px 0 #ccc;box-shadow:0 0 10px 0 #ccc}#chooseqtype .instruction,#chooseqtype .qtypesummary{position:absolute;top:0;right:0;bottom:0;left:60%;display:none;padding:1.5em 1.6em;margin:0;overflow-y:auto;background-color:#fff}#chooseqtype .instruction,#chooseqtype .selected .qtypesummary{display:block}#categoryquestions{margin:0}#categoryquestions td,#categoryquestions th{padding:0 .2em}#categoryquestions th{font-weight:normal;text-align:left}#categoryquestions .checkbox{padding-left:20px}.dir-rtl #categoryquestions th{text-align:right}.questionbank .singleselect{margin:0}#combinedfeedbackhdr div.fhtmleditor{padding:0}#combinedfeedbackhdr div.fcheckbox{margin-bottom:1em}#multitriesheader div.fitem_feditor{margin-top:1em}#multitriesheader div.fitem_fgroup{margin-bottom:1em}#multitriesheader div.fitem_fgroup fieldset.felement label{margin-right:.3em;margin-left:.3em}body.path-question-type .fitem_fgroup .accesshide{position:static;left:0;padding-right:.3em;font:inherit}.que{margin:0 auto 1.8em auto;clear:left;text-align:left}.dir-rtl .que{text-align:right}.que .info{float:left;width:7em;padding:.5em;margin-bottom:1.8em;background-color:#eee;border:1px solid #dcdcdc;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.que h2.no{margin:0;font-size:.8em;line-height:1}.que span.qno{font-size:1.5em;font-weight:bold}.que .info>div{margin-top:.7em;font-size:.8em}.que .info .questionflag.editable{cursor:pointer}.que .info .editquestion img,.que .info .questionflag img,.que .info .questionflag input{vertical-align:bottom}.que .content{margin:0 0 0 8.5em}.que .formulation,.que .outcome,.que .comment{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.que .formulation{color:#3a87ad;color:#333;background-color:#d9edf7;border-color:#bce8f1}.formulation input[type="text"],.formulation select{width:auto}.path-mod-quiz input[size]{width:auto}.que .comment{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.que .history{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.que .history blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.que .ablock{margin:.7em 0 .3em 0}.que .im-controls{margin-top:.5em;text-align:left}.dir-rtl .que .im-controls{text-align:right}.que .specificfeedback,.que .generalfeedback,.que .rightanswer,.que .im-feedback,.que .feedback,.que p{margin:0 0 .5em}.que .qtext{margin-bottom:1.5em}.que .correctness{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.que .correctness:empty{display:none}.que .correctness-important{background-color:#b94a48}.que .correctness-important[href]{background-color:#953b39}.que .correctness-warning{background-color:#f89406}.que .correctness-warning[href]{background-color:#c67605}.que .correctness-success{background-color:#468847}.que .correctness-success[href]{background-color:#356635}.que .correctness-info{background-color:#3a87ad}.que .correctness-info[href]{background-color:#2d6987}.que .correctness-inverse{background-color:#333}.que .correctness-inverse[href]{background-color:#1a1a1a}.que .correctness.correct{background-color:#468847}.que .correctness.partiallycorrect{background-color:#f89406}.que .correctness.notanswered,.que .correctness.incorrect{background-color:#b94a48}.que .validationerror{color:#b94a48}.formulation .correct{background-color:#dff0d8}.formulation .partiallycorrect{background-color:#fcf8e3}.formulation .incorrect{background-color:#f2dede}.formulation select.correct,.formulation input.correct{color:#468847;background-color:#dff0d8;border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.correct:focus,.formulation input.correct:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.formulation select.partiallycorrect,.formulation input.partiallycorrect{color:#c09853;background-color:#fcf8e3;border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.partiallycorrect:focus,.formulation input.partiallycorrect:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.formulation select.incorrect,.formulation input.incorrect{color:#b94a48;background-color:#f2dede;border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.incorrect:focus,.formulation input.incorrect:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.que .grading,.que .comment,.que .commentlink,.que .history{margin-top:.5em}.que .history h3{margin:0 0 .2em;font-size:1em}.que .history table{width:100%;margin:0}.que .history .current{font-weight:bold}.que .questioncorrectnessicon{vertical-align:text-bottom}.que input.questionflagimage{padding-right:3px}.dir-rtl .que input.questionflagimage{padding-right:0;padding-left:3px}.importerror{margin-top:10px;border-bottom:1px solid #555}.mform .que.comment .fitemtitle{width:20%}#page-question-preview #techinfo{margin:1em 0}.dir-rtl #chooseqtype .instruction,.dir-rtl #chooseqtype .qtypesummary{right:60%;left:0;border-right:1px solid grey;border-left:0}#page-mod-quiz-edit .questionbankwindow div.header{padding:3px;padding:2px 10px 2px 10px;margin:0 -10px 0 -10px;color:#444;text-shadow:none;background:transparent;-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}#page-mod-quiz-edit .questionbankwindow div.header a:link,#page-mod-quiz-edit .questionbankwindow div.header a:visited{color:#08c}#page-mod-quiz-edit .questionbankwindow div.header a:hover{color:#005580}#page-mod-quiz-edit .questionbankwindow div.header .title{color:#333}#page-mod-quiz-edit div.container div.generalbox{padding:1.5em;background-color:transparent}#page-mod-quiz-edit .categoryinfo{background-color:#fff;border-bottom:0}#page-mod-quiz-edit div.questionbank .categoryquestionscontainer,#page-mod-quiz-edit div.questionbank .categorysortopotionscontainer,#page-mod-quiz-edit div.questionbank .categorypagingbarcontainer,#page-mod-quiz-edit div.questionbank .categoryselectallcontainer{padding:0 0 1.5em 0}#page-mod-quiz-edit div.questionbank .categorypagingbarcontainer{padding:1em;margin:0 -1.2em;background-color:transparent;border-top:0;border-bottom:0}#page-mod-quiz-edit div.questionbank .categoryquestionscontainer{margin:0 -1.2em -1em -1.2em}#page-mod-quiz-edit div.question div.content div.questioncontrols{background-color:#fff}#page-mod-quiz-edit div.question div.content div.points{padding-bottom:.5em;margin-top:-0.5em;background-color:#fff;border:0}#page-mod-quiz-edit div.question div.content div.points label{display:inline-block}#page-mod-quiz-edit div.quizpage .pagecontent .pagestatus{background-color:#fff}#page-mod-quiz-edit .quizpagedelete,#page-mod-quiz-edit .quizpagedelete img{background-color:transparent}#page-mod-quiz-edit div.quizpage .pagecontent{overflow:hidden;border:1px solid #ddd;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}#page-mod-quiz-edit .modulespecificbuttonscontainer{width:220px}.questionbankwindow .module{width:auto}#page-mod-quiz-edit div.editq div.question div.content{overflow:hidden;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.path-mod-quiz .statedetails{display:block;font-size:.9em}a#hidebankcmd{color:#08c}.que.shortanswer .answer{padding:0}.que label{display:inline}.userprofile .fullprofilelink{margin:10px;text-align:center}.userprofile .description{margin-bottom:20px}.userprofile dl.list{*zoom:1}.userprofile dl.list:before,.userprofile dl.list:after{display:table;line-height:0;content:""}.userprofile dl.list:after{clear:both}.userprofile dl.list dt{float:left;width:180px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.userprofile dl.list dd{margin-left:200px}.user-box{float:left;width:115px;height:160px;margin:8px;clear:none;text-align:center}.userlist .main .action-icon img{vertical-align:middle}.userlist #showall{margin:10px 0}.userlist .buttons{text-align:center}.userlist .buttons label{padding:0 3px}.userlist table#participants{text-align:center}.userlist table#participants td,.userlist table#participants th{padding:4px;text-align:left;vertical-align:middle}.userlist table.controls{width:100%}.userlist table.controls tr{vertical-align:top}.userlist table.controls td.right,.userlist table.controls td.left{padding:4px}.userlist table.controls .right{text-align:right}.userinfobox{width:100%;padding:10px;border:1px solid;border-collapse:separate}.userinfobox .left,.userinfobox .side{width:100px;vertical-align:top}.userinfobox .userpicture{width:100px;height:100px}.userinfobox .content{vertical-align:top}.userinfobox .links{width:100px;padding:5px;vertical-align:bottom}.userinfobox .links a{display:block}.userinfobox .list td{padding:3px}.userinfobox .username{padding-bottom:20px;font-weight:bold}.userinfobox td.label{font-weight:bold;text-align:right;white-space:nowrap;vertical-align:top}.groupinfobox{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.groupinfobox blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.groupinfobox .left{width:100px;padding:10px;vertical-align:top}.course-participation #showall{margin:10px 0;text-align:center}#user-policy .noticebox{width:80%;height:250px;margin-right:auto;margin-bottom:10px;margin-left:auto;text-align:center}#user-policy #policyframe{width:100%;height:100%}.iplookup #map{margin:auto}.userselector select{width:100%}.userselector div{margin-top:.2em}.userselector div label{margin-right:.3em}.userselector .userselector-infobelow{font-size:.8em}#userselector_options{padding:.3em 0}#userselector_options .collapsibleregioncaption{font-weight:bold}#userselector_options p{margin:.2em 0;text-align:left}.dir-rtl #userselector_options p{text-align:right}#page-user-profile .messagebox{margin-right:auto;margin-left:auto;text-align:center}#page-course-view-weeks .messagebox{margin-right:auto;margin-left:auto;text-align:center}.dir-rtl .descriptionbox{margin-right:110px;margin-left:0}.dir-rtl .userlist table#participants td,.dir-rtl .userlist table#participants th{text-align:right}.dir-rtl .userlist table#participants{margin:0 auto}#page-my-index.dir-rtl .block h3.main{text-align:right}/*!
+.layout-option-noheader #page-header,.layout-option-nonavbar #page-navbar,.layout-option-nofooter #page-footer,.layout-option-nocourseheader .course-content-header,.layout-option-nocoursefooter .course-content-footer{display:none}.empty-region-side-pre #block-region-side-pre,.empty-region-side-post #block-region-side-post{display:none}.empty-region-side-post #region-bs-main-and-pre.span9{width:100%}.empty-region-side-pre #region-main{float:none;width:100%}.empty-region-side-post.used-region-side-pre #region-main.span8{width:74.46808510638297%;*width:74.41489361702126%}.empty-region-side-post.used-region-side-pre #block-region-side-pre.span4{width:23.404255319148934%;*width:23.351063829787233%}.empty-region-side-post #region-bs-main-and-post.span9 #region-main.span8{width:100%}.dir-ltr,.mdl-left,.dir-rtl .mdl-right{text-align:left}.dir-rtl,.mdl-right,.dir-rtl .mdl-left{text-align:right}#add,#remove,.centerpara,.mdl-align{text-align:center}a.dimmed,a.dimmed:link,a.dimmed:visited,a.dimmed_text,a.dimmed_text:link,a.dimmed_text:visited,.dimmed_text,.dimmed_text a,.dimmed_text a:link,.dimmed_text a:visited,.usersuspended,.usersuspended a,.usersuspended a:link,.usersuspended a:visited,.dimmed_category,.dimmed_category a{color:#999}.activity.label .dimmed_text{opacity:.5;filter:alpha(opacity=50)}.unlist,.unlist li,.inline-list,.inline-list li,.block .list,.block .list li,.section li.activity,.section li.movehere,.tabtree li{padding:0;margin:0;list-style:none}.inline,.inline-list li{display:inline}.notifytiny{font-size:10.5px}.notifytiny li,.notifytiny td{font-size:100%}.red,.notifyproblem{color:#b94a48}.green,.notifysuccess{color:#468847}.reportlink{text-align:right}a.autolink.glossary:hover{cursor:help}.collapsibleregioncaption{white-space:nowrap}.collapsibleregioncaption img{vertical-align:middle}.jsenabled .hiddenifjs{display:none}.visibleifjs{display:none}.jsenabled .visibleifjs{display:inline}.jsenabled .collapsibleregion{overflow:hidden}.jsenabled .collapsed .collapsibleregioninner{visibility:hidden}.yui-overlay .yui-widget-bd{position:relative;top:0;left:0;z-index:1;padding:2px 5px;color:#000;background-color:#ffee69;border:1px solid #a6982b;border-top-color:#d4c237}.clearer{display:block;height:1px;padding:0;margin:0;clear:both;background:transparent;border-width:0}.bold,.warning,.errorbox .title,.pagingbar .title,.pagingbar .thispage,.headingblock{font-weight:bold}img.resize{width:1em;height:1em}.block img.resize,.breadcrumb img.resize{width:.8em;height:.9em}img.icon{width:16px;height:16px;padding-right:6px;vertical-align:text-bottom}.dir-rtl img.icon{padding-right:0;padding-left:6px}img.iconsmall{width:12px;height:12px;margin-right:3px;vertical-align:middle}img.iconhelp,.helplink img{width:16px;height:16px;padding-left:3px;vertical-align:text-bottom}.dir-rtl img.iconhelp,.dir-rtl .helplink img{padding-right:3px;padding-left:0}img.iconlarge{width:24px;height:24px;vertical-align:middle}img.iconsort{padding-left:.3em;margin-bottom:.15em;vertical-align:text-bottom}.dir-rtl img.iconsort{padding-right:.3em;padding-left:0}img.icontoggle{width:50px;height:17px;vertical-align:middle}img.iconkbhelp{width:49px;height:17px}img.icon-pre,.dir-rtl img.icon-post{padding-right:3px;padding-left:0}img.icon-post,.dir-rtl img.icon-pre{padding-right:0;padding-left:3px}.boxaligncenter{margin-right:auto;margin-left:auto}.boxalignright{margin-right:0;margin-left:auto}.boxalignleft{margin-right:auto;margin-left:0}.boxwidthnarrow{width:30%}.boxwidthnormal{width:50%}.boxwidthwide{width:80%}.headermain{font-weight:bold}#maincontent{display:block;height:1px;overflow:hidden}img.uihint{cursor:help}#addmembersform table{margin-right:auto;margin-left:auto}.flexible th{white-space:nowrap}table.flexible .emptyrow{display:none}img.emoticon{width:15px;height:15px;vertical-align:middle}form.popupform,form.popupform div{display:inline}.arrow_button input{overflow:hidden}.action-icon img.smallicon{margin:0 .3em;vertical-align:text-bottom}.main img{vertical-align:middle}.no-overflow{padding-bottom:1px;overflow:auto}.pagelayout-report .no-overflow{overflow:visible}.no-overflow>.generaltable{margin-bottom:0}.accesshide{position:absolute;left:-10000px;font-size:1em;font-weight:normal}.dir-rtl .accesshide{top:-30000px;left:auto}span.hide,div.hide{display:none}a.skip-block,a.skip{position:absolute;top:-1000em;font-size:.85em;text-decoration:none}a.skip-block:focus,a.skip-block:active,a.skip:focus,a.skip:active{position:static;display:block}.skip-block-to{display:block;height:1px;overflow:hidden}.addbloglink{text-align:center}.blog_entry .audience{padding-right:4px;text-align:right}.blog_entry .tags{margin-top:15px}.blog_entry .tags .action-icon img.smallicon{width:16px;height:16px}.blog_entry .content{margin-left:43px}#page-group-index #groupeditform{text-align:center}#doc-contents h1{margin:1em 0 0 0}#doc-contents ul{width:90%;padding:0;margin:0}#doc-contents ul li{list-style-type:none}.groupmanagementtable td{vertical-align:top}.groupmanagementtable #existingcell,.groupmanagementtable #potentialcell{width:42%}.groupmanagementtable #buttonscell{width:16%}.groupmanagementtable #buttonscell p.arrow_button input{width:auto;min-width:80%;margin:0 auto}.groupmanagementtable #removeselect_wrapper,.groupmanagementtable #addselect_wrapper{width:100%}.groupmanagementtable #removeselect_wrapper label,.groupmanagementtable #addselect_wrapper label{font-weight:normal}.dir-rtl .groupmanagementtable p{text-align:right}#group-usersummary{width:14em}.groupselector{margin-top:3px;margin-bottom:3px}.loginbox{margin:15px;overflow:visible}.loginbox.twocolumns{margin:15px}.loginbox h2,.loginbox .subcontent{padding:10px;margin:5px;text-align:center}.loginbox .loginpanel .desc{padding:0;margin:0;margin-top:15px;margin-bottom:5px}.loginbox .signuppanel .subcontent{text-align:left}.dir-rtl .loginbox .signuppanel .subcontent{text-align:right}.loginbox .loginsub{margin-right:0;margin-left:0}.loginbox .guestsub,.loginbox .forgotsub,.loginbox .potentialidps{margin:5px 12%}.loginbox .potentialidps .potentialidplist{margin-left:40%}.loginbox .potentialidps .potentialidplist div{text-align:left}.loginbox .loginform{margin-top:1em;text-align:left}.loginbox .loginform .form-label{float:left;width:44%;text-align:right;white-space:nowrap;direction:rtl}.dir-rtl .loginbox .loginform .form-label{float:left;width:44%;text-align:right;white-space:nowrap;direction:ltr}.loginbox .loginform .form-input{float:right;width:55%}.loginbox .loginform .form-input input{width:6em}.loginbox .signupform{margin-top:1em;text-align:center}.loginbox.twocolumns .loginpanel,.loginbox.twocolumns .signuppanel{display:block;float:left;width:48%;min-height:30px;padding:0;padding-bottom:2000px;margin:0;margin-bottom:-2000px;margin-left:2.76243%;border:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.loginbox .potentialidp .smallicon{margin:0 .3em;vertical-align:text-bottom}.notepost{margin-bottom:1em}.notepost .userpicture{float:left;margin-right:5px}.notepost .content,.notepost .footer{clear:both}.notesgroup{margin-left:20px}.path-my .coursebox .overview{margin:15px 30px 10px 30px}.path-my .coursebox .info{float:none;margin:0}.mod_introbox{padding:10px}table.mod_index{width:100%}.comment-ctrl{display:none;padding:0;margin:0;font-size:12px}.comment-ctrl h5{padding:5px;margin:0}.comment-area{max-width:400px;padding:5px}.comment-area textarea{width:100%;overflow:auto}.comment-area .fd{text-align:right}.comment-meta span{color:gray}.comment-link img{vertical-align:text-bottom}.comment-list{padding:0;margin:0;overflow:auto;font-size:11px;list-style:none}.comment-list li{position:relative;padding:.3em;margin:2px;margin-bottom:5px;clear:both;list-style:none}.comment-list li.first{display:none}.comment-paging{text-align:center}.comment-paging .pageno{padding:2px}.comment-paging .curpage{border:1px solid #CCC}.comment-message .picture{float:left;width:20px}.dir-rtl .comment-message .picture{float:right}.comment-message .text{padding:0;margin:0}.comment-message .text p{padding:0;margin:0 18px 0 0}.comment-delete{position:absolute;top:0;right:0;margin:.3em}.dir-rtl .comment-delete{position:absolute;right:auto;left:0;margin:.3em}.comment-delete-confirm{width:5em;padding:2px;text-align:center;background:#eee}.comment-container{float:left;margin:4px}.comment-report-selectall{display:none}.comment-link{display:none}.jsenabled .comment-link{display:block}.jsenabled .showcommentsnonjs{display:none}.jsenabled .comment-report-selectall{display:inline}.completion-expired{background:#f2dede}.completion-expected{font-size:10.5px}.completion-sortchoice,.completion-identifyfield{font-size:10.5px;vertical-align:bottom}.completion-progresscell{text-align:right}.completion-expired .completion-expected{font-weight:bold}#page-tag-coursetags_edit .coursetag_edit_centered{position:relative;width:600px;margin:20px auto}#page-tag-coursetags_edit .coursetag_edit_row{clear:both}#page-tag-coursetags_edit .coursetag_edit_row .coursetag_edit_left{float:left;width:50%;text-align:right}#page-tag-coursetags_edit .coursetag_edit_row .coursetag_edit_right{margin-left:50%}#page-tag-coursetags_edit .coursetag_edit_input3{display:none}#page-tag-coursetags_more .coursetag_more_large{font-size:120%}#page-tag-coursetags_more .coursetag_more_small{font-size:80%}#page-tag-coursetags_more .coursetag_more_link{font-size:80%}#tag-description,#tag-blogs{width:100%}#tag-management-box{margin-bottom:10px;line-height:20px}#tag-user-table{width:100%;padding:3px;clear:both}#tag-user-table{*zoom:1}#tag-user-table:before,#tag-user-table:after{display:table;line-height:0;content:""}#tag-user-table:after{clear:both}img.user-image{width:100px;height:100px}#small-tag-cloud-box{width:300px;margin:0 auto}#big-tag-cloud-box{float:none;width:600px;margin:0 auto}ul#tag-cloud-list{padding:5px;margin:0;list-style:none}ul#tag-cloud-list li{display:inline;margin:0;list-style-type:none}#tag-search-box{margin:10px auto;text-align:center}#tag-search-results-container{width:100%;padding:0}#tag-search-results{display:block;float:left;width:60%;padding:0;margin:15px 20% 0 20%}#tag-search-results li{float:left;width:30%;padding-right:1%;padding-left:1%;line-height:20px;text-align:left;list-style:none}span.flagged-tag,span.flagged-tag a{color:#b94a48}table#tag-management-list{width:100%;text-align:left}table#tag-management-list td,table#tag-management-list th{padding:4px;text-align:left;vertical-align:middle}.tag-management-form{text-align:center}#relatedtags-autocomplete-container{width:100%;min-height:4.6em;margin-right:auto;margin-left:auto}#relatedtags-autocomplete{position:relative;display:block;width:60%;margin-right:auto;margin-left:auto}#relatedtags-autocomplete .yui-ac-content{position:absolute;left:20%;z-index:9050;width:420px;overflow:hidden;background:#fff;border:1px solid #404040}#relatedtags-autocomplete .ysearchquery{position:absolute;right:10px;z-index:10;color:#808080}#relatedtags-autocomplete .yui-ac-shadow{position:absolute;z-index:9049;width:100%;margin:.3em;background:#a0a0a0}#relatedtags-autocomplete ul{width:100%;padding:0;margin:0;list-style-type:none}#relatedtags-autocomplete li{padding:0 5px;white-space:nowrap;cursor:default}#relatedtags-autocomplete li.yui-ac-highlight{background:#ffc}h2.tag-heading,div#tag-description,div#tag-blogs,body.tag .managelink{padding:5px}.tag_cloud .s20{font-size:1.5em;font-weight:bold}.tag_cloud .s19{font-size:1.5em}.tag_cloud .s18{font-size:1.4em;font-weight:bold}.tag_cloud .s17{font-size:1.4em}.tag_cloud .s16{font-size:1.3em;font-weight:bold}.tag_cloud .s15{font-size:1.3em}.tag_cloud .s14{font-size:1.2em;font-weight:bold}.tag_cloud .s13{font-size:1.2em}.tag_cloud .s12,.tag_cloud .s11{font-size:1.1em;font-weight:bold}.tag_cloud .s10,.tag_cloud .s9{font-size:1.1em}.tag_cloud .s8,.tag_cloud .s7{font-size:1em;font-weight:bold}.tag_cloud .s6,.tag_cloud .s5{font-size:1em}.tag_cloud .s4,.tag_cloud .s3{font-size:.9em;font-weight:bold}.tag_cloud .s2,.tag_cloud .s1{font-size:.9em}.tag_cloud .s0{font-size:.8em}#webservice-doc-generator td{text-align:left;border:0 solid black}.smartselect{position:absolute}.smartselect .smartselect_mask{background-color:#fff}.smartselect ul{padding:0;margin:0}.smartselect ul li{list-style:none}.smartselect .smartselect_menu{margin-right:5px}.safari .smartselect .smartselect_menu{margin-left:2px}.smartselect .smartselect_menu,.smartselect .smartselect_submenu{display:none;background-color:#FFF;border:1px solid #000}.smartselect .smartselect_menu.visible,.smartselect .smartselect_submenu.visible{display:block}.smartselect .smartselect_menu_content ul li{position:relative;padding:2px 5px}.smartselect .smartselect_menu_content ul li a{color:#333;text-decoration:none}.smartselect .smartselect_menu_content ul li a.selectable{color:inherit}.smartselect .smartselect_submenuitem{background-image:url([[pix:moodle|t/collapsed]]);background-position:100%;background-repeat:no-repeat}.smartselect.spanningmenu .smartselect_submenu{position:absolute;top:-1px;left:100%}.smartselect.spanningmenu .smartselect_submenu a{padding-right:16px;white-space:nowrap}.smartselect.spanningmenu .smartselect_menu_content ul li a.selectable:hover{text-decoration:underline}.smartselect.compactmenu .smartselect_submenu{position:relative;z-index:1010;display:none;margin:2px -3px;margin-left:10px;border-width:0}.smartselect.compactmenu .smartselect_submenu.visible{display:block}.smartselect.compactmenu .smartselect_menu{z-index:1000;overflow:hidden}.smartselect.compactmenu .smartselect_submenu .smartselect_submenu{z-index:1020}.smartselect.compactmenu .smartselect_submenuitem:hover>.smartselect_menuitem_label{font-weight:bold}#page-admin-registration-register .registration_textfield{width:300px}.userenrolment{width:100%;border-collapse:collapse}.userenrolment td{height:41px;padding:0}.userenrolment .subfield{margin-right:5px}.userenrolment .col_userdetails .subfield_picture{float:left}.userenrolment .col_lastseen{width:150px}.userenrolment .col_role{width:262px}.userenrolment .col_role .roles{margin-right:30px}.userenrolment .col_role .role{float:left;padding:3px;margin:3px}.dir-rtl .userenrolment .col_role .role{float:right}.userenrolment .col_role .role a{margin-left:3px;cursor:pointer}.userenrolment .col_role .addrole{float:right;width:18px;height:18px;margin:3px;text-align:center;background-color:#dff0d8;border:1px solid #d6e9c6}.userenrolment .col_role .addrole img{vertical-align:baseline}.userenrolment .hasAllRoles .col_role .addrole{display:none}.userenrolment .col_group .groups{margin-right:30px}.userenrolment .col_group .group{float:left;padding:3px;margin:3px;white-space:nowrap}.userenrolment .col_group .group a{margin-left:3px;cursor:pointer}.userenrolment .col_group .addgroup{float:right;width:18px;height:18px;margin:3px;text-align:center}.userenrolment .col_group .addgroup a img{vertical-align:bottom}.userenrolment .col_enrol .enrolment{float:left;padding:3px;margin:3px}.userenrolment .col_enrol .enrolment a{float:right;margin-left:3px}#page-enrol-users .enrol_user_buttons{float:right}#page-enrol-users.dir-rtl .enrol_user_buttons{float:left}#page-enrol-users .enrol_user_buttons .enrolusersbutton{display:inline;margin-left:1em}#page-enrol-users .enrol_user_buttons .enrolusersbutton div,#page-enrol-users .enrol_user_buttons .enrolusersbutton form{display:inline}#page-enrol-users .enrol_user_buttons .enrolusersbutton input{padding-right:6px;padding-left:6px}#page-enrol-users.dir-rtl .col_userdetails .subfield_picture{float:right}#page-enrol-users .user-enroller-panel .uep-search-results .user .details{width:237px}.dir-rtl .headermain{float:right}.dir-rtl .headermenu{float:left}.dir-rtl .loginbox .loginform .form-label{float:right;text-align:left}.dir-rtl .loginbox .loginform .form-input{text-align:right}.dir-rtl .yui3-menu-hidden{left:0}#page-admin-roles-define.dir-rtl #rolesform .felement{margin-right:180px}#page-message-edit.dir-rtl table.generaltable th.c0{text-align:right}.corelightbox{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;background-color:#CCC}.corelightbox img{position:fixed;top:50%;left:50%}.mod-indent-1{margin-left:30px}.mod-indent-2{margin-left:60px}.mod-indent-3{margin-left:90px}.mod-indent-4{margin-left:120px}.mod-indent-5{margin-left:150px}.mod-indent-6{margin-left:180px}.mod-indent-7{margin-left:210px}.mod-indent-8{margin-left:240px}.mod-indent-9{margin-left:270px}.mod-indent-10{margin-left:300px}.mod-indent-11{margin-left:330px}.mod-indent-12{margin-left:360px}.mod-indent-13{margin-left:390px}.mod-indent-14{margin-left:420px}.mod-indent-15,.mod-indent-huge{margin-left:420px}.dir-rtl .mod-indent-1{margin-right:30px;margin-left:0}.dir-rtl .mod-indent-2{margin-right:60px;margin-left:0}.dir-rtl .mod-indent-3{margin-right:90px;margin-left:0}.dir-rtl .mod-indent-4{margin-right:120px;margin-left:0}.dir-rtl .mod-indent-5{margin-right:150px;margin-left:0}.dir-rtl .mod-indent-6{margin-right:180px;margin-left:0}.dir-rtl .mod-indent-7{margin-right:210px;margin-left:0}.dir-rtl .mod-indent-8{margin-right:240px;margin-left:0}.dir-rtl .mod-indent-9{margin-right:270px;margin-left:0}.dir-rtl .mod-indent-10{margin-right:300px;margin-left:0}.dir-rtl .mod-indent-11{margin-right:330px;margin-left:0}.dir-rtl .mod-indent-12{margin-right:360px;margin-left:0}.dir-rtl .mod-indent-13{margin-right:390px;margin-left:0}.dir-rtl .mod-indent-14{margin-right:420px;margin-left:0}.dir-rtl .mod-indent-15,.dir-rtl .mod-indent-huge{margin-right:420px;margin-left:0}.resourcecontent .mediaplugin_mp3 object{width:600px;height:25px}.resourcecontent audio.mediaplugin_html5audio{width:600px}.resourceimage{max-width:100%}.mediaplugin_mp3 object{width:300px;height:15px}audio.mediaplugin_html5audio{width:300px}.core_media_preview.pagelayout-embedded #content{padding:0}.core_media_preview.pagelayout-embedded #maincontent{height:0}.core_media_preview.pagelayout-embedded .mediaplugin{margin:0}.dir-rtl .ygtvtn,.dir-rtl .ygtvtm,.dir-rtl .ygtvtmh,.dir-rtl .ygtvtmhh,.dir-rtl .ygtvtp,.dir-rtl .ygtvtph,.dir-rtl .ygtvtphh,.dir-rtl .ygtvln,.dir-rtl .ygtvlm,.dir-rtl .ygtvlmh,.dir-rtl .ygtvlmhh,.dir-rtl .ygtvlp,.dir-rtl .ygtvlph,.dir-rtl .ygtvlphh,.dir-rtl .ygtvdepthcell,.dir-rtl .ygtvok,.dir-rtl .ygtvok:hover,.dir-rtl .ygtvcancel,.dir-rtl .ygtvcancel:hover{width:18px;height:22px;cursor:pointer;background-image:url([[pix:theme|yui2-treeview-sprite-rtl]]);background-repeat:no-repeat}.dir-rtl .ygtvtn{background-position:0 -5600px}.dir-rtl .ygtvtm{background-position:0 -4000px}.dir-rtl .ygtvtmh,.dir-rtl .ygtvtmhh{background-position:0 -4800px}.dir-rtl .ygtvtp{background-position:0 -6400px}.dir-rtl .ygtvtph,.dir-rtl .ygtvtphh{background-position:0 -7200px}.dir-rtl .ygtvln{background-position:0 -1600px}.dir-rtl .ygtvlm{background-position:0 0}.dir-rtl .ygtvlmh,.dir-rtl .ygtvlmhh{background-position:0 -800px}.dir-rtl .ygtvlp{background-position:0 -2400px}.dir-rtl .ygtvlph,.dir-rtl .ygtvlphh{background-position:0 -3200px}.dir-rtl .ygtvdepthcell{background-position:0 -8000px}.dir-rtl .ygtvok{background-position:0 -8800px}.dir-rtl .ygtvok:hover{background-position:0 -8844px}.dir-rtl .ygtvcancel{background-position:0 -8822px}.dir-rtl .ygtvcancel:hover{background-position:0 -8866px}.dir-rtl.yui-skin-sam .yui-panel .hd{text-align:right}.dir-rtl .yui-skin-sam .yui-layout .yui-layout-unit div.yui-layout-bd{text-align:right}.dir-rtl .clearlooks2.ie9 .mceAlert .mceMiddle span,.dir-rtl .clearlooks2 .mceConfirm .mceMiddle span{top:44px}.dir-rtl .o2k7Skin table,.dir-rtl .o2k7Skin tbody,.dir-rtl .o2k7Skin a,.dir-rtl .o2k7Skin img,.dir-rtl .o2k7Skin tr,.dir-rtl .o2k7Skin div,.dir-rtl .o2k7Skin td,.dir-rtl .o2k7Skin iframe,.dir-rtl .o2k7Skin span,.dir-rtl .o2k7Skin *,.dir-rtl .o2k7Skin .mceText,.dir-rtl .o2k7Skin .mceListBox .mceText{text-align:right}.path-rating .ratingtable{width:100%;margin-bottom:1em}.path-rating .ratingtable th.rating{width:100%}.path-rating .ratingtable td.rating,.path-rating .ratingtable td.time{text-align:center;white-space:nowrap}.initialbar a{padding-right:2px}.moodle-dialogue-base .moodle-dialogue-lightbox{background-color:#AAA}.moodle-dialogue-base .hidden,.moodle-dialogue-base .moodle-dialogue-hidden{display:none}.no-scrolling{overflow:hidden}.moodle-dialogue-fullscreen{top:0;left:0;width:100%;height:100%;overflow:auto}.moodle-dialogue-base .moodle-dialogue{z-index:600;padding:0;margin:0;background:0;border:0;outline:#000 dotted 0}.moodle-dialogue-base .moodle-dialogue-wrap{margin-top:-3px;margin-left:-3px;background-color:#fff;border:1px solid #ccc;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd{padding:5px;margin:0;font-size:12px;font-weight:normal;letter-spacing:1px;color:#333;text-align:center;text-shadow:1px 1px 1px #fff;background:#ccc;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border-bottom:1px solid #bbb;-webkit-border-radius:10px 10px 0 0;-moz-border-radius:10px 10px 0 0;border-radius:10px 10px 0 0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0);filter:dropshadow(color=#ffffff,offx=1,offy=1)}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd h1{display:inline;padding:0;margin:0;font-size:100%;font-weight:bold}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd .yui3-widget-buttons{padding:5px}.moodle-dialogue-base .closebutton{display:inline-block;float:right;width:25px;height:15px;padding:0;vertical-align:middle;cursor:pointer;background-image:url([[pix:theme|sprite]]);background-repeat:no-repeat;border-style:none}.dir-rtl .moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-hd .yui3-widget-buttons{right:auto;left:0}.moodle-dialogue-base .moodle-dialogue .moodle-dialogue-bd{padding:1em;overflow:auto;font-size:12px;line-height:2em;color:#555}.moodle-dialogue-base .moodle-dialogue-wrap .moodle-dialogue-content{padding:0;background:#FFF}.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-hd{padding:10px;font-size:16px}.moodle-dialogue-base .moodle-dialogue-fullscreen,.moodle-dialogue-fullscreen .moodle-dialogue-content{width:100%;height:100%;margin:0;border:0}.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-hd,.moodle-dialogue-base .moodle-dialogue-fullscreen .moodle-dialogue-wrap{border-radius:0}.moodle-dialogue-confirm .confirmation-dialogue{text-align:center}.moodle-dialogue-confirm .confirmation-dialogue input{text-align:center}.moodle-dialogue-exception .moodle-exception-message{text-align:center}.moodle-dialogue-exception .moodle-exception-param label{font-weight:bold}.moodle-dialogue-exception .param-stacktrace label{background-color:#EEE;border:1px solid #ccc;border-bottom-width:0}.moodle-dialogue-exception .param-stacktrace pre{background-color:#fff;border:1px solid #ccc}.moodle-dialogue-exception .param-stacktrace .stacktrace-file{font-size:11.9px;color:navy}.moodle-dialogue-exception .param-stacktrace .stacktrace-line{font-size:11.9px;color:#b94a48}.moodle-dialogue-exception .param-stacktrace .stacktrace-call{font-size:90%;color:#333;border-bottom:1px solid #eee}.moodle-dialogue-base .moodle-dialogue .moodle-dialogue-content .moodle-dialogue-ft{padding:0;margin:.7em 1em;font-size:12px;text-align:right;background-color:#FFF}.moodle-dialogue-confirm .confirmation-message{margin:.5em 1em}.moodle-dialogue-confirm .confirmation-dialogue input{min-width:80px}.moodle-dialogue-exception .moodle-exception-message{margin:1em}.moodle-dialogue-exception .moodle-exception-param{margin-bottom:.5em}.moodle-dialogue-exception .moodle-exception-param label{width:150px}.moodle-dialogue-exception .param-stacktrace label{display:block;padding:4px 1em;margin:0}.moodle-dialogue-exception .param-stacktrace pre{display:block;height:200px;overflow:auto}.moodle-dialogue-exception .param-stacktrace .stacktrace-file{display:inline-block;margin:4px 0}.moodle-dialogue-exception .param-stacktrace .stacktrace-line{display:inline-block;width:50px;margin:4px 1em}.moodle-dialogue-exception .param-stacktrace .stacktrace-call{padding-bottom:4px;padding-left:25px;margin-bottom:4px}.moodle-dialogue .moodle-dialogue-bd .content-lightbox{top:0;left:0;width:100%;height:100%;padding:10% 0;text-align:center;background-color:white;opacity:.75;filter:alpha(opacity=75)}.moodle-dialogue .tooltiptext{max-height:300px}.moodle-dialogue-base .moodle-dialogue.moodle-dialogue-tooltip{z-index:3001}#page-question-edit.dir-rtl a.container-close{right:auto;left:6px}.chooserdialoguebody,.choosertitle{display:none}.moodle-dialogue.chooserdialogue .moodle-dialogue-content .moodle-dialogue-ft{margin:0}.chooserdialogue .moodle-dialogue-wrap .moodle-dialogue-bd{padding:0;background:#f2f2f2;-webkit-border-bottom-right-radius:10px;border-bottom-right-radius:10px;-webkit-border-bottom-left-radius:10px;border-bottom-left-radius:10px;-moz-border-radius-bottomright:10px;-moz-border-radius-bottomleft:10px}.choosercontainer #chooseform .submitbuttons{margin:.7em 0;text-align:center}.choosercontainer #chooseform .submitbuttons input{min-width:100px;margin:0 .5em}.choosercontainer #chooseform .options{position:relative;border-bottom:1px solid #bbb}.jsenabled .choosercontainer #chooseform .alloptions{max-width:20.3em;overflow-x:hidden;overflow-y:auto;-webkit-box-shadow:inset 0 0 30px 0 #ccc;-moz-box-shadow:inset 0 0 30px 0 #ccc;box-shadow:inset 0 0 30px 0 #ccc}.dir-rtl.jsenabled .choosercontainer #chooseform .alloptions{max-width:18.3em}.choosercontainer #chooseform .moduletypetitle,.choosercontainer #chooseform .option,.choosercontainer #chooseform .nonoption{padding:0 1.6em 0 1.6em;margin-bottom:0}.choosercontainer #chooseform .moduletypetitle{padding-top:1.2em;padding-bottom:.4em;text-transform:uppercase}.choosercontainer #chooseform .option .typename,.choosercontainer #chooseform .option span.modicon img.icon,.choosercontainer #chooseform .nonoption .typename,.choosercontainer #chooseform .nonoption span.modicon img.icon{padding:0 0 0 .5em}.dir-rtl .choosercontainer #chooseform .option .typename,.dir-rtl .choosercontainer #chooseform .option span.modicon img.icon,.dir-rtl .choosercontainer #chooseform .nonoption .typename,.dir-rtl .choosercontainer #chooseform .nonoption span.modicon img.icon{padding:0 .5em 0 0}.choosercontainer #chooseform .option span.modicon img.icon,.choosercontainer #chooseform .nonoption span.modicon img.icon{width:24px;height:24px}.choosercontainer #chooseform .option input[type=radio],.choosercontainer #chooseform .option span.typename,.choosercontainer #chooseform .option span.modicon{vertical-align:middle}.choosercontainer #chooseform .option label{display:block;padding:.3em 0 .1em 0;border-bottom:1px solid #fff}.choosercontainer #chooseform .nonoption{padding-top:.3em;padding-bottom:.1em;padding-left:2.7em}.dir-rtl .choosercontainer #chooseform .nonoption{padding-right:2.7em;padding-left:0}.choosercontainer #chooseform .subtype{padding:0 1.6em 0 3.2em;margin-bottom:0}.dir-rtl .choosercontainer #chooseform .subtype{padding:0 3.2em 0 1.6em}.choosercontainer #chooseform .subtype .typename{margin:0 0 0 .2em}.dir-rtl .choosercontainer #chooseform .subtype .typename{margin:0 .2em 0 0}.jsenabled .choosercontainer #chooseform .instruction,.jsenabled .choosercontainer #chooseform .typesummary{position:absolute;top:0;right:0;bottom:0;left:20.3em;display:none;padding:1.6em;margin:0;overflow-x:hidden;overflow-y:auto;line-height:2em;background-color:#fff}.dir-rtl.jsenabled .choosercontainer #chooseform .instruction,.dir-rtl.jsenabled .choosercontainer #chooseform .typesummary{right:18.5em;left:0;border-right:1px solid grey}.jsenabled .choosercontainer #chooseform .instruction,.choosercontainer #chooseform .selected .typesummary{display:block}.choosercontainer #chooseform .selected{background-color:#fff;-webkit-box-shadow:0 0 10px 0 #ccc;-moz-box-shadow:0 0 10px 0 #ccc;box-shadow:0 0 10px 0 #ccc}.section-modchooser-link img.smallicon{padding:3px}.formlistingradio{padding-right:10px;padding-bottom:25px}.formlistinginputradio{float:left}.formlistingmain{min-height:225px}.formlisting{position:relative;padding:1px 19px 14px;margin:15px 0;background-color:white;border:1px solid #DDD;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.formlistingmore{position:absolute;right:-1px;bottom:-1px;padding:3px 7px;font-size:12px;font-weight:bold;color:#9da0a4;cursor:pointer;background-color:whiteSmoke;border:1px solid #ddd;-webkit-border-radius:4px 0 4px 0;-moz-border-radius:4px 0 4px 0;border-radius:4px 0 4px 0}.formlistingall{padding:0;margin:15px 0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.formlistingrow{top:50%;left:50%;float:left;width:150px;min-height:34px;padding:6px;cursor:pointer;background-color:#f7f7f9;border-right:1px solid #e1e1e8;border-bottom:1px solid;border-left:1px solid #e1e1e8;border-color:#e1e1e8;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px}body.jsenabled .formlistingradio{display:none}body.jsenabled .formlisting{display:block}table.collection{width:100%;margin-bottom:20px;border:1px solid #ddd;border-collapse:separate;*border-collapse:collapse;border-left:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}table.collection th,table.collection td{padding:8px;line-height:20px;text-align:left;vertical-align:top;border-top:1px solid #ddd}table.collection th{font-weight:bold}table.collection thead th{vertical-align:bottom}table.collection caption+thead tr:first-child th,table.collection caption+thead tr:first-child td,table.collection colgroup+thead tr:first-child th,table.collection colgroup+thead tr:first-child td,table.collection thead:first-child tr:first-child th,table.collection thead:first-child tr:first-child td{border-top:0}table.collection tbody+tbody{border-top:2px solid #ddd}table.collection .table{background-color:#fff}table.collection th,table.collection td{border-left:1px solid #ddd}table.collection caption+thead tr:first-child th,table.collection caption+tbody tr:first-child th,table.collection caption+tbody tr:first-child td,table.collection colgroup+thead tr:first-child th,table.collection colgroup+tbody tr:first-child th,table.collection colgroup+tbody tr:first-child td,table.collection thead:first-child tr:first-child th,table.collection tbody:first-child tr:first-child th,table.collection tbody:first-child tr:first-child td{border-top:0}table.collection thead:first-child tr:first-child>th:first-child,table.collection tbody:first-child tr:first-child>td:first-child,table.collection tbody:first-child tr:first-child>th:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}table.collection thead:first-child tr:first-child>th:last-child,table.collection tbody:first-child tr:first-child>td:last-child,table.collection tbody:first-child tr:first-child>th:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}table.collection thead:last-child tr:last-child>th:first-child,table.collection tbody:last-child tr:last-child>td:first-child,table.collection tbody:last-child tr:last-child>th:first-child,table.collection tfoot:last-child tr:last-child>td:first-child,table.collection tfoot:last-child tr:last-child>th:first-child{-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px}table.collection thead:last-child tr:last-child>th:last-child,table.collection tbody:last-child tr:last-child>td:last-child,table.collection tbody:last-child tr:last-child>th:last-child,table.collection tfoot:last-child tr:last-child>td:last-child,table.collection tfoot:last-child tr:last-child>th:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px}table.collection tfoot+tbody:last-child tr:last-child td:first-child{-webkit-border-bottom-left-radius:0;border-bottom-left-radius:0;-moz-border-radius-bottomleft:0}table.collection tfoot+tbody:last-child tr:last-child td:last-child{-webkit-border-bottom-right-radius:0;border-bottom-right-radius:0;-moz-border-radius-bottomright:0}table.collection caption+thead tr:first-child th:first-child,table.collection caption+tbody tr:first-child td:first-child,table.collection colgroup+thead tr:first-child th:first-child,table.collection colgroup+tbody tr:first-child td:first-child{-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topleft:4px}table.collection caption+thead tr:first-child th:last-child,table.collection caption+tbody tr:first-child td:last-child,table.collection colgroup+thead tr:first-child th:last-child,table.collection colgroup+tbody tr:first-child td:last-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-moz-border-radius-topright:4px}table.collection tbody>tr:nth-child(odd)>td,table.collection tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}table.collection .name{text-align:left;vertical-align:middle}table.collection .awards{width:10%;text-align:center;vertical-align:middle}table.collection .criteria{width:40%;text-align:left;vertical-align:top}table.collection .badgeimage,table.collection .status{width:15%;text-align:center;vertical-align:middle}table.collection .description{width:25%;text-align:left}table.collection .actions{width:11em;text-align:center;vertical-align:middle}a.criteria-action{float:right;padding:0 3px}table.issuedbadgebox{width:750px;background-color:#fff}table.badgeissuedimage{width:150px;text-align:center}table.badgeissuedinfo{width:600px}table.badgeissuedinfo .bvalue{text-align:left;vertical-align:middle}table.badgeissuedinfo .bfield{width:125px;font-style:italic;text-align:left}ul.badges{margin:0;list-style:none}.badges li{position:relative;display:inline-block;width:150px;padding-bottom:2em;text-align:center;vertical-align:top}.badges li .badge-name{display:block;padding:5px}.badges li>img{position:absolute}.badges li .badge-image{top:0;left:10px;z-index:1;width:90px;height:90px}.badges li .badge-actions{position:relative}div.badge{position:relative;display:block}div.badge .expireimage{top:0;left:20px;width:100px;height:100px}.expireimage{position:absolute;top:0;left:30px;z-index:10;width:90px;height:90px;opacity:.85;filter:alpha(opacity=85)}.badge-profile{vertical-align:top}.connected{color:#468847}.notconnected{color:#b94a48}#page-badges-award .recipienttable tr td{vertical-align:top}#page-badges-award .recipienttable tr td.actions .actionbutton{width:100%;padding:.5em 0;margin:.3em 0}#page-badges-award .recipienttable tr td.existing,#page-badges-award .recipienttable tr td.potential{width:42%}.statustable{margin-bottom:0}.statusbox.active{background-color:#dff0d8}.statusbox.inactive{background-color:#fcf8e3}.activatebadge{margin:0;text-align:left;vertical-align:middle}.addcourse{float:right}.invisiblefieldset{display:inline;padding:0;margin:0;border-width:0}.breadcrumb-nav{float:left;margin-bottom:10px}.dir-rtl .breadcrumb-nav{float:right}.breadcrumb-button .singlebutton div{margin-right:0}.breadcrumb-nav .breadcrumb{margin:0}.moodle-actionmenu,.moodle-actionmenu>ul,.moodle-actionmenu>ul>li{display:inline-block}.moodle-actionmenu ul{padding:0;margin:0;list-style-type:none}.moodle-actionmenu .toggle-display,.moodle-actionmenu .menu-action-text{display:none}.jsenabled .moodle-actionmenu[data-enhance]{display:block}.jsenabled .moodle-actionmenu[data-enhance] .menu{display:none}.jsenabled .moodle-actionmenu[data-enhance] .toggle-display{display:inline;opacity:.5;filter:alpha(opacity=50)}.jsenabled .moodle-actionmenu[data-enhanced] .toggle-display{opacity:1;filter:alpha(opacity=100)}.jsenabled .moodle-actionmenu[data-enhanced] .menu-action-text{display:inline}.moodle-actionmenu[data-enhanced].show{position:relative}.moodle-actionmenu[data-enhanced].show .menu{position:absolute;z-index:1000;display:block;text-align:left;background-color:#fff;border:1px solid #ccc;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}.moodle-actionmenu[data-enhanced].show .menu a{display:block;padding:2px 1em 2px .5em;color:#333}.moodle-actionmenu[data-enhanced].show .menu a:hover,.moodle-actionmenu[data-enhanced].show .menu a:focus{color:#fff;background-color:#08c}.moodle-actionmenu[data-enhanced].show .menu a:first-child{-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}.moodle-actionmenu[data-enhanced].show .menu a:last-child{-webkit-border-bottom-right-radius:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;border-bottom-left-radius:4px;-moz-border-radius-bottomright:4px;-moz-border-radius-bottomleft:4px}.moodle-actionmenu[data-enhanced].show .menu a.hidden{display:none}.moodle-actionmenu[data-enhanced].show .menu img{vertical-align:middle}.moodle-actionmenu[data-enhanced].show .menu .iconsmall{margin-right:8px}.moodle-actionmenu[data-enhanced].show .menu>li{display:block}.moodle-actionmenu[data-enhanced].show .menu.align-tl-bl{top:100%;left:0;margin-top:4px}.moodle-actionmenu[data-enhanced].show .menu.align-tr-bl{top:100%;right:100%}.moodle-actionmenu[data-enhanced].show .menu.align-bl-bl{bottom:100%;left:0}.moodle-actionmenu[data-enhanced].show .menu.align-br-bl{right:100%;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-br{top:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tr-br{top:100%;right:0;margin-top:4px}.moodle-actionmenu[data-enhanced].show .menu.align-bl-br{bottom:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-br-br{right:0;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-tl{top:0;left:0}.moodle-actionmenu[data-enhanced].show .menu.align-tr-tl{top:0;right:100%;margin-right:4px}.moodle-actionmenu[data-enhanced].show .menu.align-bl-tl{bottom:100%;left:0;margin-bottom:4px}.moodle-actionmenu[data-enhanced].show .menu.align-br-tl{right:100%;bottom:100%}.moodle-actionmenu[data-enhanced].show .menu.align-tl-tr{top:0;left:100%;margin-left:4px}.moodle-actionmenu[data-enhanced].show .menu.align-tr-tr{top:0;right:0}.moodle-actionmenu[data-enhanced].show .menu.align-bl-tr{bottom:100%;left:100%}.moodle-actionmenu[data-enhanced].show .menu.align-br-tr{right:0;bottom:100%;margin-bottom:4px}.action-menu-shown .moodle-actionmenu[data-enhanced] .toggle-display{background-color:#FFF}.block .moodle-actionmenu{text-align:right}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu{right:auto;left:0;text-align:right}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu .iconsmall{margin-right:0;margin-left:8px}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-bl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-bl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-bl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-bl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-br{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-br{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-br{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-br{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-tl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-tl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-tl{right:0;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-tl{right:auto;left:100%}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tl-tr{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-tr-tr{right:auto;left:0}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-bl-tr{right:100%;left:auto}.dir-rtl .moodle-actionmenu[data-enhanced].show .menu.align-br-tr{right:auto;left:0}.dir-rtl .block .moodle-actionmenu{text-align:right}ul.dragdrop-keyboard-drag li{list-style-type:none}.block-control-actions .moodle-core-dragdrop-draghandle img{width:12px;height:12px}.formtable tbody th{font-weight:normal;text-align:right}.path-admin #assignrole{width:60%;margin-right:auto;margin-left:auto}.path-admin .admintable .leftalign{text-align:left}.environmenttable p.warn{color:#c09853;background-color:#fcf8e3}.environmenttable .error,.environmenttable span.warn,.environmenttable .ok{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.environmenttable .error:empty,.environmenttable span.warn:empty,.environmenttable .ok:empty{display:none}.environmenttable .error-important,.environmenttable span.warn-important,.environmenttable .ok-important{background-color:#b94a48}.environmenttable .error-important[href],.environmenttable span.warn-important[href],.environmenttable .ok-important[href]{background-color:#953b39}.environmenttable .error-warning,.environmenttable span.warn-warning,.environmenttable .ok-warning{background-color:#f89406}.environmenttable .error-warning[href],.environmenttable span.warn-warning[href],.environmenttable .ok-warning[href]{background-color:#c67605}.environmenttable .error-success,.environmenttable span.warn-success,.environmenttable .ok-success{background-color:#468847}.environmenttable .error-success[href],.environmenttable span.warn-success[href],.environmenttable .ok-success[href]{background-color:#356635}.environmenttable .error-info,.environmenttable span.warn-info,.environmenttable .ok-info{background-color:#3a87ad}.environmenttable .error-info[href],.environmenttable span.warn-info[href],.environmenttable .ok-info[href]{background-color:#2d6987}.environmenttable .error-inverse,.environmenttable span.warn-inverse,.environmenttable .ok-inverse{background-color:#333}.environmenttable .error-inverse[href],.environmenttable span.warn-inverse[href],.environmenttable .ok-inverse[href]{background-color:#1a1a1a}.environmenttable .error{background-color:#b94a48}.environmenttable span.warn{background-color:#f89406}.environmenttable .ok{background-color:#468847}.path-admin .admintable.environmenttable .name,.path-admin .admintable.environmenttable .info,.path-admin #assignrole .admintable .role,.path-admin #assignrole .admintable .userrole,.path-admin #assignrole .admintable .roleholder{white-space:nowrap}.path-admin .incompatibleblockstable td.c0{font-weight:bold}#page-admin-course-category .addcategory{padding:10px}#page-admin-course-index .editcourse{margin:20px auto}#page-admin-course-index .editcourse th,#page-admin-course-index .editcourse td{padding-right:10px;padding-left:10px}.timewarninghidden{display:none}.statusok,.statuswarning,.statusserious,.statuscritical{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.statusok:empty,.statuswarning:empty,.statusserious:empty,.statuscritical:empty{display:none}.statusok-important,.statuswarning-important,.statusserious-important,.statuscritical-important{background-color:#b94a48}.statusok-important[href],.statuswarning-important[href],.statusserious-important[href],.statuscritical-important[href]{background-color:#953b39}.statusok-warning,.statuswarning-warning,.statusserious-warning,.statuscritical-warning{background-color:#f89406}.statusok-warning[href],.statuswarning-warning[href],.statusserious-warning[href],.statuscritical-warning[href]{background-color:#c67605}.statusok-success,.statuswarning-success,.statusserious-success,.statuscritical-success{background-color:#468847}.statusok-success[href],.statuswarning-success[href],.statusserious-success[href],.statuscritical-success[href]{background-color:#356635}.statusok-info,.statuswarning-info,.statusserious-info,.statuscritical-info{background-color:#3a87ad}.statusok-info[href],.statuswarning-info[href],.statusserious-info[href],.statuscritical-info[href]{background-color:#2d6987}.statusok-inverse,.statuswarning-inverse,.statusserious-inverse,.statuscritical-inverse{background-color:#333}.statusok-inverse[href],.statuswarning-inverse[href],.statusserious-inverse[href],.statuscritical-inverse[href]{background-color:#1a1a1a}.statusok{background-color:#468847}.statuswarning{background-color:#c09853}.statusserious{background-color:#f89406}.statuscritical{background-color:#b94a48}#page-admin-report-capability-index #capabilitysearch{width:30em}#page-admin-report-backups-index .backup-error,#page-admin-report-backups-index .backup-unfinished{color:#b94a48}#page-admin-report-backups-index .backup-skipped,#page-admin-report-backups-index .backup-ok{color:#468847}#page-admin-report-backups-index .backup-warning{color:#c09853}#page-admin-qtypes .disabled,#page-admin-qbehaviours .disabled{color:#999}#page-admin-qtypes #qtypes div,#page-admin-qtypes #qtypes form,#page-admin-qbehaviours #qbehaviours div,#page-admin-qbehaviours #qbehaviours form{display:inline}#page-admin-qtypes #qtypes img.spacer,#page-admin-qbehaviours #qbehaviours img.spacer{width:16px}img.iconsmall{padding:.3em;margin:0}#page-admin-qbehaviours .cell.c3,#page-admin-qtypes .cell.c3{font-size:10.5px}#page-admin-lang .generalbox,#page-admin-course-index .singlebutton,#page-admin-course-index .addcategory,#page-course-index .buttons,#page-course-index-category .buttons,#page-admin-course-category .addcategory,#page-admin-stickyblocks .generalbox,#page-admin-maintenance .buttons,#page-admin-course-index .buttons,#page-admin-course-category .buttons,#page-admin-index .copyright,#page-admin-index .copyrightnotice,#page-admin-index .adminerror,#page-admin-index .availableupdatesinfo,#page-admin-index .adminerror .singlebutton,#page-admin-index .adminwarning .singlebutton,#page-admin-index #layout-table .singlebutton{margin-bottom:1em;text-align:center}.path-admin-roles .capabilitysearchui{margin-right:auto;margin-left:auto;text-align:left}#page-admin-roles-define .topfields{margin:1em 0 2em}#page-admin-roles-define .capdefault{background-color:#eee;border:1px solid #cecece}#page-filter-manage .backlink,.path-admin-roles .backlink{margin-top:1em}#page-admin-roles-explain #chooseuser h3,#page-admin-roles-usersroles .contextname{margin-top:0}#page-admin-roles-explain #chooseusersubmit{margin-top:0;text-align:center}#page-admin-roles-usersroles p{margin:0}#page-admin-roles-override .cell.c1,#page-admin-roles-assign .cell.c3,#page-admin-roles-assign .cell.c1{padding-top:.75em}#page-admin-roles-override .overridenotice,#page-admin-roles-define .definenotice{margin:1em 10% 2em 10%;text-align:left}#notice{width:60%;min-width:220px;margin:auto}#page-admin-index .releasenoteslink,#page-admin-index .adminwarning,#page-admin-index .maturitywarning,#page-admin-index .maturityinfo{width:60%;min-width:220px;padding:8px 35px 8px 14px;margin:auto;margin-bottom:20px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}#page-admin-index .maturitywarning,#page-admin-index .adminwarning.maturityinfo.maturity50{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}#page-admin-index .adminwarning.availableupdatesinfo,#page-admin-index .releasenoteslink{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo span{display:block}#page-admin-index .updateplugin div,#page-admin-plugins .updateplugin div{margin-bottom:.5em}#page-admin-index .updateplugin .updatepluginconfirmexternal,#page-admin-plugins .updateplugin .updatepluginconfirmexternal{padding:1em;background-color:#f2dede;border:1px solid #eed3d7}#page-admin-user-user_bulk #users .fgroup{white-space:nowrap}#page-admin-report-stats-index .graph{margin-bottom:1em;text-align:center}#page-admin-report-courseoverview-index .graph{margin-bottom:1em;text-align:center}#page-admin-lang .translator{border-style:solid;border-width:1px}.path-admin .roleassigntable{width:100%}.path-admin .roleassigntable td{padding:.2em .3em;vertical-align:top}.path-admin .roleassigntable p{margin:.2em 0;text-align:left}.path-admin .roleassigntable #existingcell,.path-admin .roleassigntable #potentialcell{width:42%}.path-admin .roleassigntable #existingcell p>label:first-child,.path-admin .roleassigntable #potentialcell p>label:first-child{font-weight:bold}.path-admin .roleassigntable #buttonscell{width:16%}.path-admin .roleassigntable #buttonscell #assignoptions{font-size:10.5px}.path-admin .roleassigntable #removeselect_wrapper,.path-admin .roleassigntable #addselect_wrapper{width:100%}.path-admin table.rolecap tr.rolecap th{font-weight:normal;text-align:left}.path-admin.dir-rtl table.rolecap tr.rolecap th{text-align:right}.path-admin .rolecap .hiddenrow{display:none}.path-admin #defineroletable .rolecap .inherit,.path-admin #defineroletable .rolecap .allow,.path-admin #defineroletable .rolecap .prevent,.path-admin #defineroletable .rolecap .prohibit{min-width:3.5em;padding:0;text-align:center}.path-admin .rolecap .cap-name,.path-admin .rolecap .note{display:block;font-size:10.5px;font-weight:normal;white-space:nowrap}.path-admin .rolecap label{display:block;padding:.5em;margin:0;text-align:center}.plugincheckwrapper{width:100%}.environmentbox{margin-top:1em}#mnetconfig table{margin-right:auto;margin-left:auto}.environmenttable .cell{padding:.15em .5em}.environmenttable img.iconhelp{padding-right:.3em}.dir-rtl .environmenttable img.iconhelp{padding-right:0;padding-left:.3em}#trustedhosts .generaltable{width:500px;margin-right:auto;margin-left:auto}#trustedhosts .standard{width:auto}#adminsettings legend{display:none}#adminsettings fieldset.error{margin:.2em 0 .5em 0}#adminsettings fieldset.error legend{display:block}.dir-rtl #admin-spelllanguagelist textarea,#page-admin-setting-editorsettingstinymce.dir-rtl .form-textarea textarea{text-align:left;direction:ltr}.adminsettingsflags{float:right}.dir-rtl .adminsettingsflags{float:left}.adminsettingsflags label{margin-right:7px}.dir-rtl .adminsettingsflags label{margin-left:7px}.form-description{clear:right}.dir-rtl .form-description{clear:left}.form-item .form-setting .form-htmlarea{display:inline;width:640px}.form-item .form-setting .form-htmlarea .htmlarea{display:block;width:640px}.form-item .form-setting .form-multicheckbox ul{padding:0;margin:7px 0 0 0;list-style:none}.form-item .form-setting .defaultsnext{display:inline;margin-right:.5em}.dir-rtl .form-item .form-setting .defaultsnext{margin-right:0;margin-left:.5em}.form-item .form-setting .locked-checkbox{display:inline;margin-right:.2em;margin-left:.5em}.dir-rtl .form-item .form-setting .locked-checkbox{display:inline;margin-right:.5em;margin-left:.2em}.form-item .form-setting .form-password .unmask,.form-item .form-setting .form-defaultinfo{display:inline-block}.form-item .pathok,.form-item .patherror{margin-left:.5em}#admin-devicedetectregex table{border:0}#admin-emoticons td input{width:8em}#admin-emoticons td.c0 input{width:4em}#adminthemeselector .selectedtheme td.c0{border:1px solid;border-right-width:0}#adminthemeselector .selectedtheme td.c1{border:1px solid;border-left-width:0}.admin_colourpicker,.admin_colourpicker_preview{display:none}.jsenabled .admin_colourpicker_preview{display:inline}.jsenabled .admin_colourpicker{display:block;width:410px;height:102px;margin-bottom:10px}.admin_colourpicker .loadingicon{margin-left:auto;vertical-align:middle}.admin_colourpicker .colourdialogue{float:left;border:1px solid #000}.admin_colourpicker .previewcolour{margin-left:301px;border:1px solid #000}.admin_colourpicker .currentcolour{margin-left:301px;border:1px solid #000;border-top-width:0}.dir-rtl .form-item .form-setting,.dir-rtl .form-item .form-label,.dir-rtl .form-item .form-description,.dir-rtl.path-admin .roleassigntable p{text-align:right}#page-admin-index #notice .checkforupdates{text-align:center}#plugins-check-info{margin:1em;text-align:center}#plugins-check .displayname .pluginicon{width:16px}#plugins-check .status-new .status{background-color:#dff0d8}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity200 .info.release,#plugins-check .status-upgrade .status,#plugins-check .status-delete .status{background-color:#d9edf7}#plugins-control-panel .extension .source,#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity100 .info.release,#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity150 .info.release,.pluginupdateinfo.maturity100,.pluginupdateinfo.maturity150,#plugins-check .extension .source{background-color:#fcf8e3}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo.maturity50 .info.release,.pluginupdateinfo.maturity50,#plugins-check .requires-failed,#plugins-check .missingfromdisk .displayname,#plugins-check .status-missing .status,#plugins-check .status-downgrade .status{background-color:#f2dede}#plugins-control-panel .statusmsg{padding:3px;background-color:#eee;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#plugins-control-panel .status-missing .pluginname{background-color:#f2dede}#plugins-control-panel .status-missing .statusmsg{color:#b94a48}#plugins-control-panel .status-new .pluginname{background-color:#dff0d8}#plugins-control-panel .status-new .statusmsg{color:#468847}#plugins-control-panel .disabled .availability{background-color:#eee}#plugins-check .standard .source,#plugins-check .status-nodb .status,#plugins-check .status-uptodate .status,#plugins-check .requires-ok{color:#999}#plugins-check .requires ul{margin:0;font-size:10.5px}#plugins-check .status .pluginupdateinfo{padding:5px 10px;margin:10px;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-check .status .pluginupdateinfo span,#plugins-check .status .pluginupdateinfo a{padding-right:1em}#page-admin-index .upgradepluginsinfo{text-align:center}#page-admin-plugins .checkforupdates{margin:0 auto 1em;text-align:center}#plugins-control-panel .requiredby,#plugins-control-panel .pluginname .componentname{font-size:11.9px;color:#999}#plugins-control-panel .pluginname .componentname{margin-left:22px}#plugins-overview-filter .filter-item,#plugins-overview-panel .info{padding:0 10px}#page-admin-index .adminwarning.availableupdatesinfo .moodleupdateinfo .separator,#plugins-check .status .pluginupdateinfo .separator,#page-admin-plugins .separator{border-left:1px dotted #999}#plugins-control-panel .msg td{text-align:center}#plugins-overview-filter,#plugins-overview-panel{margin:1em auto;text-align:center}#plugins-overview-panel .info.updatable{margin-left:10px;font-weight:bold;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-overview-filter .filter-item.active{font-weight:bold}#plugins-control-panel .displayname img.icon{padding-top:0;padding-bottom:0}#plugins-control-panel .uninstall a{color:#b94a48}#plugins-control-panel .notes .pluginupdateinfo{padding:5px 10px;margin:10px;background-color:#d9edf7;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}#plugins-control-panel .notes .pluginupdateinfo span,#plugins-control-panel .notes .pluginupdateinfo a{padding-right:1em}.dir-rtl #plugins-check .pluginupdateinfo{text-align:center;direction:ltr}.dir-rtl #plugins-check .rootdir,.dir-rtl #plugins-check .requires-ok{text-align:left;direction:ltr}#page-admin-mnet-peers .box.deletedhosts{margin-bottom:1em;font-size:11.9px}#page-admin-mnet-peers .mform .certdetails{background-color:white}#page-admin-mnet-peers .mform .deletedhostinfo{padding:4px;margin-bottom:5px;background-color:#f2dede;border:2px solid #eed3d7}#core-cache-plugin-summaries table,#core-cache-store-summaries table{width:100%}#core-cache-lock-summary table,#core-cache-definition-summaries table,#core-cache-mode-mappings table{margin:0 auto}#core-cache-store-summaries .default-store td{font-style:italic;color:#333}#core-cache-rescan-definitions,#core-cache-mode-mappings .edit-link,#core-cache-lock-summary .new-instance{margin-top:.5em;text-align:center}.tinymcesubplugins img.icon{padding-top:0;padding-bottom:0}#page-admin-roles-assign div.box.generalbox{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;color:#b94a48;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;background-color:#f2dede;border:1px solid #fbeed5;border-color:#eed3d7;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.calendartable{width:100%}.calendartable th,.calendartable td{width:14%;text-align:center;vertical-align:top;border:0}.calendar_event_course{background-color:#ffd3bd}.calendar_event_global{background-color:#d6f8cd}.calendar_event_group{background-color:#fee7ae}.calendar_event_user{background-color:#dce7ec}.path-calendar .calendar-controls .previous,.path-calendar .calendar-controls .next,.path-calendar .calendar-controls .current{display:block;float:left;width:12%}.path-calendar .calendar-controls .previous{text-align:left}.path-calendar .calendar-controls .current{width:76%;text-align:center}.path-calendar .calendar-controls .next{text-align:right}.path-calendar .maincalendar{padding:0;vertical-align:top}.path-calendar .maincalendar .bottom{padding:5px 0 0 0;text-align:center}.path-calendar .maincalendar .heightcontainer{position:relative;height:100%}.path-calendar .maincalendar .calendarmonth{width:98%;margin:10px auto}.path-calendar .maincalendar .calendarmonth ul{margin:0}.path-calendar .maincalendar .calendarmonth ul li{margin-top:4px;list-style-type:none}.path-calendar .maincalendar .calendarmonth td{height:5em}.path-calendar .maincalendar .calendar-controls .previous,.path-calendar .maincalendar .calendar-controls .next{width:30%}.path-calendar .maincalendar .calendar-controls .current{width:39.95%}.path-calendar .maincalendar .controls{width:98%;margin:10px auto}.path-calendar .maincalendar .eventlist .event{width:100%;margin-bottom:10px;border-collapse:separate;border-spacing:0;border-style:solid;border-width:1px}.path-calendar .maincalendar .eventlist .event .topic .name{float:left}.dir-rtl.path-calendar .maincalendar .eventlist .event .topic .name,.path-calendar .maincalendar .eventlist .event .topic .date{float:right}.dir-rtl.path-calendar .maincalendar .eventlist .event .topic .date{float:left}.path-calendar .maincalendar .eventlist .event .subscription,.path-calendar .maincalendar .eventlist .event .course{float:left;clear:left}.dir-rtl.path-calendar .maincalendar .eventlist .event .subscription,.dir-rtl.path-calendar .maincalendar .eventlist .event .course{float:right;clear:right}.path-calendar .maincalendar .eventlist .event .side{width:32px}.path-calendar .maincalendar .eventlist .event .commands a{margin:0 3px}.path-calendar .maincalendar .header{overflow:hidden}.path-calendar .maincalendar .header .buttons{float:right}.dir-rtl.path-calendar .maincalendar .header .buttons{float:left}.path-calendar .filters table{width:100%;border-collapse:separate;border-spacing:2px}#page-calendar-export .indent{padding-left:20px}.path-calendar .cal_courses_flt label{margin-right:.45em}.dir-rtl.path-calendar .cal_courses_flt label{margin-right:0;margin-left:.45em}.block .minicalendar th,.block .minicalendar td{padding:2px;font-size:.8em}.block .minicalendar{max-width:280px;margin-right:auto;margin-left:auto}.block .minicalendar td.weekend{color:#A00}.block .calendar-controls .previous{display:block;float:left;width:12%;text-align:left}.block .calendar-controls .current{display:block;float:left;width:76%;text-align:center}.block .calendar-controls .next{display:block;float:left;width:12%;text-align:right}.block .calendar_filters ul{margin:0;list-style:none}.block .calendar_filters li{margin-bottom:.2em}.block .calendar_filters li span img{padding:0 .2em}.block .calendar_filters .eventname{padding-left:.2em}.dir-rtl .block .calendar_filters .eventname{padding-right:.2em;padding-left:0}.block .content h3.eventskey{margin-top:.5em}@media(min-width:768px){#page-calender-view .container fluid{min-width:1024px}}.section_add_menus{text-align:right}.dir-rtl .section_add_menus{text-align:left}.section_add_menus .horizontal div,.section_add_menus .horizontal form{display:inline}.section_add_menus optgroup{font-style:italic;font-weight:normal}.section_add_menus .urlselect{margin-left:.4em}.dir-rtl .section_add_menus .urlselect{margin-right:.4em;margin-left:0}.section_add_menus .urlselect select{margin-left:.2em}.dir-rtl .section_add_menus .urlselect select{margin-right:.2em;margin-left:0}.section_add_menus .urlselect img.iconhelp{padding:0;margin:0;vertical-align:text-bottom}.site-topic ul.section,.course-content ul.section{margin:1em}.section .activity img.activityicon{margin-right:6px}.dir-rtl .section .activity img.activityicon{margin-right:0;margin-left:6px}.section .activity .activityinstance,.section .activity .activityinstance div{display:inline-block}.editing .section .activity .activityinstance{min-width:40%}.section .activity .activityinstance>a{display:block}.editing_show+.editing_assign,.editing_hide+.editing_assign{margin-left:20px}.section .activity .commands{display:inline;white-space:nowrap}.section .activity.modtype_label .commands{padding-left:22px;margin-left:40%}.section .activity.modtype_label.label{font-weight:normal}.section li.activity{padding:.2em;clear:both}.section .activity .activityinstance .groupinglabel{padding-left:30px}.dir-rtl .section .activity .activityinstance .groupinglabel{padding-right:30px}.section .activity .availabilityinfo,.section .activity .contentafterlink{margin-top:.5em;margin-left:30px}.dir-rtl .section .activity .availabilityinfo,.dir-rtl .section .activity .contentafterlink{margin-right:30px;margin-left:0}.section .activity .contentafterlink p{margin:.5em 0}.editing .section .activity:hover,.editing .section .activity.action-menu-shown{background-color:#eee}.course-content .current{background-color:#d9edf7}.course-content .section-summary{margin-top:5px;list-style:none;border:1px solid #DDD}.course-content .section-summary .section-title{margin:2px 5px 10px 5px}.course-content .section-summary .summarytext{margin:2px 5px 2px 5px}.course-content .section-summary .section-summary-activities .activity-count{display:inline-block;margin:3px;font-size:11.9px;color:#999;white-space:nowrap}.course-content .section-summary .summary{margin-top:5px}.course-content .single-section{margin-top:1em}.course-content .single-section .section-navigation{display:block;padding:.5em;margin-bottom:-0.5em}.course-content .single-section .section-navigation .title{clear:both;font-size:108%;font-weight:bold}.course-content .single-section .section-navigation .mdl-left{float:left;margin-right:1em;font-weight:normal}.dir-rtl .course-content .single-section .section-navigation .mdl-left{float:right}.course-content .single-section .section-navigation .mdl-left .larrow{margin-right:.1em}.course-content .single-section .section-navigation .mdl-right{float:right;margin-left:1em;font-weight:normal}.dir-rtl .course-content .single-section .section-navigation .mdl-right{float:left}.course-content .single-section .section-navigation .mdl-right .rarrow{margin-left:.1em}.course-content .single-section .section-navigation .mdl-bottom{margin-top:0}.course-content ul li.section.main{margin-top:0;border-bottom:2px solid #eee}.course-content ul li.section.hidden{opacity:.5}.course-content ul.topics li.section .content,.course-content ul.weeks li.section .content{padding:0;margin-right:20px;margin-left:20px}.course-content{margin-top:0}.course-content ul.topics li.section{padding-bottom:20px}.course-content ul.topics li.section .summary{margin-left:25px}.path-course-view .completionprogress{margin-left:25px}.path-course-view .completionprogress{position:relative;z-index:1000;display:block;float:right;height:20px}#page-site-index .subscribelink{text-align:right}#page-site-index .headingblock{margin-bottom:9px}.path-course-view a.reduce-sections{padding-left:.2em}.path-course-view .headingblock{margin-bottom:9px}.path-course-view .subscribelink{text-align:right}.path-course-view .unread{margin-left:30px}.dir-rtl.path-course-view .unread{margin-right:30px}.path-course-view .block.drag .header{cursor:move}.path-course-view .completionprogress{text-align:right}.dir-rtl.path-course-view .completionprogress{text-align:left}.path-course-view .single-section .completionprogress{margin-right:5px}.path-course-view .section .summary{line-height:normal}.path-site li.activity>div,.path-course-view li.activity>div{position:relative}.path-course-view li.activity span.autocompletion,.path-course-view li.activity form.togglecompletion{float:right}.path-course-view li.activity form.togglecompletion .ajaxworking{width:16px;height:16px;background:url([[pix:i/ajaxloader]]) no-repeat}.dir-rtl.path-course-view li.activity form.togglecompletion,.dir-rtl.path-course-view li.activity span.autocompletion{float:left}.dir-rtl.path-course-view .completionprogress{float:none}.dir-rtl.path-course-view li.activity form.togglecompletion .ajaxworking{right:-22px}li.section.hidden span.commands a.editing_hide,li.section.hidden span.commands a.editing_show{cursor:default}ul.weeks h3.sectionname{white-space:nowrap}.editing ul.weeks h3.sectionname{white-space:normal}.section img.movetarget{width:80px;height:16px}input.titleeditor{width:330px;vertical-align:text-bottom}span.editinstructions{position:absolute;top:0;left:0;z-index:9999;padding:.1em .4em;margin-top:-22px;margin-left:30px;font-size:11.9px;line-height:16px;color:#3a87ad;text-decoration:none;background-color:#d9edf7;border:1px solid #bce8f1;-webkit-box-shadow:2px 2px 5px 1px #ccc;-moz-box-shadow:2px 2px 5px 1px #ccc;box-shadow:2px 2px 5px 1px #ccc}.dir-rtl span.editinstructions{right:32px;left:auto}#dndupload-status{position:absolute;z-index:9999;z-index:0;width:40%;padding:6px;margin:0 30%;color:#3a87ad;text-align:center;background:#d9edf7;border:1px solid #bce8f1;-webkit-border-bottom-right-radius:8px;border-bottom-right-radius:8px;-webkit-border-bottom-left-radius:8px;border-bottom-left-radius:8px;-moz-border-radius-bottomright:8px;-moz-border-radius-bottomleft:8px;-webkit-box-shadow:2px 2px 5px 1px #ccc;-moz-box-shadow:2px 2px 5px 1px #ccc;box-shadow:2px 2px 5px 1px #ccc}.dndupload-preview{padding:.3em;margin-top:.2em;color:#909090;list-style:none;border:1px dashed #909090}.dndupload-preview img.icon{padding:0;vertical-align:text-bottom}.dndupload-progress-outer{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f7f7f7;background-image:-moz-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-webkit-gradient(linear,0 0,0 100%,from(#f5f5f5),to(#f9f9f9));background-image:-webkit-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:-o-linear-gradient(top,#f5f5f5,#f9f9f9);background-image:linear-gradient(to bottom,#f5f5f5,#f9f9f9);background-repeat:repeat-x;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#fff9f9f9',GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.dndupload-progress-inner{float:left;width:0;height:100%;font-size:12px;color:#fff;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top,#149bdf,#0480be);background-image:-webkit-gradient(linear,0 0,0 100%,from(#149bdf),to(#0480be));background-image:-webkit-linear-gradient(top,#149bdf,#0480be);background-image:-o-linear-gradient(top,#149bdf,#0480be);background-image:linear-gradient(to bottom,#149bdf,#0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf',endColorstr='#ff0480be',GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width .6s ease;-moz-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.dndupload-hidden{display:none}#page-course-pending .singlebutton,#page-course-index .singlebutton,#page-course-index-category .singlebutton,#page-course-editsection .singlebutton{text-align:center}#page-admin-course-manage #movecourses td img{margin:0 .22em;vertical-align:text-bottom}#page-admin-course-manage #movecourses td img.icon{padding:0}#coursesearch{margin-top:1em;text-align:center}#page-course-pending .pendingcourserequests{margin-bottom:1em}#page-course-pending .pendingcourserequests .singlebutton{display:inline}#page-course-pending .pendingcourserequests .cell{padding:0 5px}#page-course-pending .pendingcourserequests .cell.c6{white-space:nowrap}.coursebox{padding:5px;margin-bottom:15px;border:1px dotted #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.coursebox>.info>.name a{display:block;padding-left:21px;background-image:url([[pix:moodle|i/course]]);background-position:center left;background-repeat:no-repeat}.coursebox.remotehost>.info>.name a{background-image:url([[pix:moodle|i/mnethost]])}.coursebox>.info>.name,.coursebox .content .teachers,.coursebox .content .courseimage,.coursebox .content .coursefile{float:left;width:40%;clear:left}.coursebox>.info>h3.name{margin:5px}.coursebox>.info>.name{padding:0;margin:5px}.coursebox .content .teachers li{padding:0;margin:0;list-style-type:none}.coursebox .enrolmenticons{float:right;padding:3px 0}.coursebox .moreinfo{float:right;padding:3px 0}.coursebox .enrolmenticons img,.coursebox .moreinfo img{margin:0 .2em}.coursebox .content{clear:both}.coursebox .content .summary,.coursebox .content .coursecat{float:right;width:55%}.coursebox .content .coursecat{clear:right;text-align:right}.coursebox.remotecoursebox .remotecourseinfo{float:left;width:40%}.coursebox .content .courseimage img{max-width:100px;max-height:100px}.coursebox .content .coursecat,.coursebox .content .summary,.coursebox .content .courseimage,.coursebox .content .coursefile,.coursebox .content .teachers,.coursebox.remotecoursebox .remotecourseinfo{padding:0;margin:3px 5px}.dir-rtl .coursebox>.info>.name a{padding-right:21px;padding-left:0;background-position:center right}.dir-rtl .coursebox>.info>.name,.dir-rtl .coursebox .teachers,.dir-rtl .coursebox .content .courseimage,.dir-rtl .coursebox .content .coursefile{float:right;clear:right}.dir-rtl .coursebox .enrolmenticons,.dir-rtl .coursebox .moreinfo{float:left}.dir-rtl .coursebox .summary,.dir-rtl .coursebox .coursecat{float:left}.dir-rtl .coursebox .coursecat{clear:left;text-align:left}.coursebox.collapsed{margin-bottom:0}.coursebox.collapsed>.content{display:none}.courses .coursebox.collapsed{padding:3px 0;border:1px solid #eee}.courses .coursebox.even{background-color:#f6f6f6}.courses .coursebox:hover,.course_category_tree .courses>.paging.paging-morelink:hover{background-color:#eee}.course_category_tree .category .numberofcourse{font-size:11.9px}.course_category_tree .controls{visibility:hidden}.course_category_tree .controls div{display:inline;cursor:pointer}.jsenabled .course_category_tree .controls{visibility:visible}.course_category_tree .controls{float:right;margin-bottom:5px;text-align:right}.course_category_tree .controls div{padding-right:2em;font-size:75%}.course_category_tree .category>.info .name{padding:2px 18px;margin:3px;background-image:url([[pix:moodle|t/collapsed_empty]]);background-position:center left;background-repeat:no-repeat}.dir-rtl .course_category_tree .category>.info .name{background-image:url([[pix:moodle|t/collapsed_empty_rtl]]);background-position:center right}.course_category_tree .category.with_children>.info .name{background-image:url([[pix:moodle|t/expanded]])}.course_category_tree .category.with_children.collapsed>.info .name{background-image:url([[pix:moodle|t/collapsed]])}.dir-rtl .course_category_tree .category.with_children.collapsed>.info .name{background-image:url([[pix:moodle|t/collapsed_rtl]])}.course_category_tree .category.collapsed>.content{display:none}.course_category_tree .category>.info{min-height:20px;min-height:0;padding:19px;padding:0;margin:3px 0;margin-bottom:20px;margin-bottom:3px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.course_category_tree .category>.info blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.course_category_tree.frontpage-category-names .category>.info{margin:0;background:0;border:0}.course_category_tree .category>.content{padding-left:16px}.dir-rtl .course_category_tree .category>.content{padding-right:16px;padding-left:0}.course_category_tree .subcategories>.paging,.courses>.paging{padding:5px;margin:0;text-align:center}.courses>.paging.paging-morelink,.course_category_tree .subcategories>.paging.paging-morelink{text-align:left}.course_category_tree .paging.paging-morelink a{font-size:11.9px}.dir-rtl .courses>.paging.paging-morelink,.dir-rtl .course_category_tree .paging.paging-morelink{text-align:right}#page-course-index-category .generalbox.info{padding:5px;margin-bottom:15px;border:1px dotted #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}#page-course-index-category .categorypicker{margin:10px 0 20px;text-align:center}.section .activity .moodle-actionmenu .iconsmall{width:16px;width:1rem;height:16px;height:1rem;max-width:none!important;padding:.3em}.filemanager,.filepicker,.file-picker{font-size:11px}.filemanager a,.file-picker a,.filemanager a:hover,.file-picker a:hover{color:#555;text-decoration:none}.filemanager input[type="text"],.file-picker input[type="text"]{width:265px}.filemanager .fp-license td,.file-picker .fp-setlicense td{max-width:265px}.filemanager .fp-license select,.file-picker .fp-setlicense select{max-width:100%}.fp-content-center{display:table-cell;width:100%;height:100%;vertical-align:middle}.fp-content-hidden{visibility:hidden}.yui3-panel-focused{outline:0}#filesskin .yui3-panel-content{display:inline-block;*display:inline;padding-bottom:20px;background:#f2f2f2;border:1px solid #fff;-webkit-border-radius:8px;-moz-border-radius:8px;border-radius:8px;*zoom:1;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}#filesskin .yui3-widget-hd{padding:5px;font-size:12px;letter-spacing:1px;color:#333;text-align:center;text-shadow:1px 1px 1px #fff;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border-bottom:1px solid #bbb;-webkit-border-radius:10px 10px 0 0;-moz-border-radius:10px 10px 0 0;border-radius:10px 10px 0 0;filter:dropshadow(color=#ffffff,offx=1,offy=1);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0)}.fp-panel-button{display:inline-block;*display:inline;padding:3px 20px 2px 20px;margin:10px;text-align:center;background:#fff;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;*zoom:1;-webkit-box-shadow:2px 2px 3px .1px #999;-moz-box-shadow:2px 2px 3px .1px #999;box-shadow:2px 2px 3px .1px #999}.filepicker .moodle-dialogue-wrap .moodle-dialogue-bd{padding:0}#filesskin .file-picker.fp-generallayout{position:relative;width:859px;background:#fff;border:1px solid #ccc;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px}.file-picker .fp-repo-area{display:inline-block;*display:inline;float:left;width:180px;height:525px;overflow:auto;border-right:1px solid #bbb;*zoom:1}.dir-rtl .file-picker .fp-repo-area{float:right;border-right:0;border-left:1px solid #bbb}.file-picker .fp-repo-items{float:left;width:693px}.dir-rtl .file-picker .fp-repo-items{float:right}.file-picker .fp-navbar{min-height:22px;padding:5px 8px;background:#f2f2f2;border-bottom:1px solid #bbb}.file-picker .fp-content{height:468px;overflow:auto;clear:both;background:#fff}.filepicker.moodle-dialogue-fullscreen .file-picker .fp-content{width:100%;height:100%}.dir-rtl .file-picker .fp-repo-items{margin-right:181px}.file-picker .fp-content-loading{display:table;width:100%;height:100%;text-align:center}.file-picker .fp-content .fp-object-container{width:98%;height:98%}.dir-rtl .file-picker .fp-list{text-align:right}.dir-rtl .file-picker .fp-toolbar{padding:0}.dir-rtl .file-picker .fp-list{text-align:right}.dir-rtl .file-picker .fp-repo-name{display:inline}.dir-rtl .file-picker .fp-pathbar{display:block;text-align:right;border-top:0}.dir-rtl .file-picker div.bd{text-align:right}.dir-rtl #filemenu .yuimenuitemlabel{text-align:right}.dir-rtl .filepicker .yui-layout-unit-left{left:500px}.dir-rtl .filepicker .yui-layout-unit-center{left:0}.dir-rtl .filemanager-toolbar a{padding:0}.file-picker .fp-list{float:left;width:100%;padding:0;margin:0;list-style-type:none}.dir-rtl .file-picker .fp-list{float:left;text-align:right}.file-picker .fp-list .fp-repo a{display:block;padding:.5em .7em}.file-picker .fp-list .fp-repo.active{background:#f2f2f2}.file-picker .fp-list .fp-repo-icon{padding:0 7px 0 5px}.fp-toolbar{display:table-row;float:left;max-width:70%;line-height:22px}.dir-rtl .fp-toolbar{float:right}.fp-toolbar.empty{display:none}.fp-toolbar .disabled{display:none}.fp-toolbar div{display:inline-block;*display:inline;padding:0 2px;padding-right:10px;*zoom:1}.dir-rtl .fp-toolbar div{width:100px;padding-right:0}.fp-toolbar img{margin-right:5px;vertical-align:-15%}.fp-toolbar .fp-tb-search{width:228px;height:14px}.fp-toolbar .fp-tb-search input{width:200px;height:16px;padding:2px 6px 1px 20px;background:#fff url('[[pix:a/search]]') no-repeat 3px 3px;border:1px solid #bbb}.fp-viewbar{float:right;width:69px;height:22px;margin-right:8px}.dir-rtl .fp-toolbar img{vertical-align:-35%}.dir-rtl .fp-viewbar{float:left;width:100px}.fp-vb-icons{display:inline-block;*display:inline;width:22px;height:22px;background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-icons{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0}.fp-vb-icons.checked{background:url('[[pix:theme|fp/view_icon_selected]]')}.dir-rtl .fp-vb-icons.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_icon_selected]]')}.fp-viewbar.disabled .fp-vb-icons{background:url('[[pix:theme|fp/view_icon_inactive]]')}.fp-vb-details{display:inline-block;*display:inline;width:23px;height:22px;margin-left:-4px;background:url('[[pix:theme|fp/view_list_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-details{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_list_active]]') no-repeat 0 0}.fp-vb-details.checked{background:url('[[pix:theme|fp/view_list_selected]]')}.dir-rtl .fp-vb-details.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_list_selected]]')}.fp-viewbar.disabled .fp-vb-details{background:url('[[pix:theme|fp/view_list_inactive]]')}.fp-vb-tree{display:inline-block;*display:inline;width:23px;height:22px;margin-left:-4px;background:url('[[pix:theme|fp/view_tree_active]]') no-repeat 0 0;*zoom:1}.dir-rtl .fp-vb-tree{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_tree_active]]') no-repeat 0 0}.fp-vb-tree.checked{background:url('[[pix:theme|fp/view_tree_selected]]')}.dir-rtl .fp-vb-tree.checked{display:block;float:left;margin-right:4px;background:url('[[pix:theme|fp/view_tree_selected]]')}.fp-viewbar.disabled .fp-vb-tree{background:url('[[pix:theme|fp/view_tree_inactive]]')}.file-picker .fp-clear-left{clear:left}.dir-rtl .filemanager-toolbar .fp-vb-icons a:hover{background:url('[[pix:theme|fp/view_icon_selected]]')}.dir-rtl .filemanager-toolbar .fp-vb-icons.checked a:hover{background:url('[[pix:theme|fp/view_icon_active]]') no-repeat 0 0}.dir-rtl .fp-vb-details a:hover{background:0;border:20px solid black}.dir-rtl .fp-vb-details.checked a:hover{background:0;border:40px solid black}.dir-rtl .fp-vb-tree a:hover{background:0;border:30px solid black}.dir-rtl .fp-vb-tree.checked a:hover{background:0;border:50px solid black}.file-picker .fp-pathbar{display:table-row}.fp-pathbar.empty{display:none}.fp-pathbar .fp-path-folder{width:27px;height:12px;margin-left:4px;background:url('[[pix:theme|fp/path_folder]]') no-repeat 0 0}.dir-rtl .fp-pathbar .fp-path-folder{width:auto;height:12px;margin-left:4px;background:url('[[pix:theme|fp/path_folder_rtl]]') no-repeat right top}.dir-rtl .fp-pathbar span{display:inline-block;*display:inline;float:right;margin-left:32px;*zoom:1}.fp-pathbar .fp-path-folder-name{margin-left:32px;line-height:20px}.dir-rtl .fp-pathbar .fp-path-folder-name{margin-right:32px;line-height:20px}.fp-iconview .fp-file{position:relative;float:left;margin:10px 10px 35px;text-align:center}.fp-iconview .fp-thumbnail{display:block;min-width:110px;min-height:110px;line-height:110px;text-align:center;border:1px solid #fff}.fp-iconview .fp-thumbnail img{padding:3px;vertical-align:middle;border:1px solid #ddd;-webkit-box-shadow:1px 1px 2px 0 #ccc;-moz-box-shadow:1px 1px 2px 0 #ccc;box-shadow:1px 1px 2px 0 #ccc}.fp-iconview .fp-thumbnail:hover{background:#fff;border:1px solid #ddd;-webkit-box-shadow:inset 0 0 10px 0 #ccc;-moz-box-shadow:inset 0 0 10px 0 #ccc;box-shadow:inset 0 0 10px 0 #ccc}.fp-iconview .fp-filename-field{position:absolute;height:33px;overflow:hidden;word-wrap:break-word}.fp-iconview .fp-filename-field:hover{z-index:1000;overflow:visible}.fp-iconview .fp-filename-field .fp-filename{min-width:112px;padding-top:5px;padding-bottom:12px;background:#fff}.dir-rtl .fp-iconview .fp-file{float:right}.file-picker .yui3-datatable table{width:100%;border:0 solid #bbb}#filesskin .file-picker .yui3-datatable-header{color:#555;background:#fff;border-bottom:1px solid #ccc;border-left:0 solid #fff}#filesskin .file-picker .yui3-datatable-odd .yui3-datatable-cell{background-color:#f6f6f6;border-left:0 solid #f6f6f6}#filesskin .file-picker .yui3-datatable-even .yui3-datatable-cell{background-color:#fff;border-left:0 solid #fff}.dir-rtl .file-picker .yui3-datatable-header{text-align:right}.file-picker .ygtvtn,.filemanager .ygtvtn{width:17px;height:22px;background:url('[[pix:moodle|y/tn]]') 0 0 no-repeat}.dir-rtl .filemanager .ygtvtn,.dir-rtl .file-picker .ygtvtn{width:17px;height:22px;background:url('[[pix:moodle|y/tn_rtl]]') 0 0 no-repeat}.file-picker .ygtvtm,.filemanager .ygtvtm{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tm]]') 0 10px no-repeat}.file-picker .ygtvtmh,.filemanager .ygtvtmh{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tm]]') 0 10px no-repeat}.file-picker .ygtvtp,.filemanager .ygtvtp{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/tp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvtp,.dir-rtl .filemanager .ygtvtp{background:url('[[pix:moodle|y/tp_rtl]]') 0 10px no-repeat}.file-picker .ygtvtph,.filemanager .ygtvtph{width:13px;height:22px;cursor:pointer;background:url('[[pix:moodle|y/tp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvtph,.dir-rtl .filemanager .ygtvtph{background:url('[[pix:moodle|y/tp_rtl]]') 0 10px no-repeat}.file-picker .ygtvln,.filemanager .ygtvln{width:17px;height:22px;background:url('[[pix:moodle|y/ln]]') 0 0 no-repeat}.dir-rtl .file-picker .ygtvln,.dir-rtl .filemanager .ygtvln{background:url('[[pix:moodle|y/ln_rtl]]') 0 0 no-repeat}.file-picker .ygtvlm,.filemanager .ygtvlm{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lm]]') 0 10px no-repeat}.file-picker .ygtvlmh,.filemanager .ygtvlmh{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lm]]') 0 10px no-repeat}.file-picker .ygtvlp,.filemanager .ygtvlp{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvlp,.dir-rtl .filemanager .ygtvlp{background:url('[[pix:moodle|y/lp_rtl]]') 0 10px no-repeat}.file-picker .ygtvlph,.filemanager .ygtvlph{width:13px;height:12px;cursor:pointer;background:url('[[pix:moodle|y/lp]]') 0 10px no-repeat}.dir-rtl .file-picker .ygtvlph,.dir-rtl .filemanager .ygtvlph{background:url('[[pix:moodle|y/lp_rtl]]') 0 10px no-repeat}.file-picker .ygtvloading,.filemanager .ygtvloading{width:16px;height:22px;background:transparent url('[[pix:moodle|y/loading]]') 0 0 no-repeat}.file-picker .ygtvdepthcell,.filemanager .ygtvdepthcell{width:17px;height:32px;background:url('[[pix:moodle|y/vline]]') 0 0 no-repeat}.file-picker .ygtvblankdepthcell,.filemanager .ygtvblankdepthcell{width:17px;height:22px}a.ygtvspacer:hover{color:transparent;text-decoration:none}.ygtvlabel,.ygtvlabel:link,.ygtvlabel:visited,.ygtvlabel:hover{margin-left:2px;text-decoration:none;cursor:pointer;background-color:transparent}.file-picker .ygtvfocus,.filemanager .ygtvfocus{background-color:#eee}.fp-filename-icon{position:relative;display:block;margin-top:10px}.fp-icon{float:left;width:24px;height:24px;margin-top:-7px;margin-right:10px;line-height:24px;text-align:center}.dir-rtl .fp-icon{float:right;margin-right:0;margin-left:10px}.fp-icon img{max-width:24px;max-height:24px;vertical-align:middle}.fp-filename{padding-right:10px}.dir-rtl .fp-filename{padding-right:0;padding-left:10px}.file-picker .fp-login-form{display:table;width:100%;height:100%}.file-picker .fp-login-form table{margin:0 auto}.file-picker .fp-login-form p{margin-top:3em;text-align:center}.file-picker .fp-login-form .fp-login-input label{display:block;text-align:right}.file-picker .fp-login-form .fp-login-input .input{text-align:left}.file-picker .fp-login-form input[type="checkbox"]{width:15px;height:15px}.file-picker .fp-upload-form{display:table;width:100%;height:100%}.file-picker .fp-upload-form table{margin:0 auto}.file-picker.fp-dlg{text-align:center}.file-picker.fp-dlg .fp-dlg-text{padding:30px 20px 10px;font-size:12px}.file-picker.fp-dlg .fp-dlg-buttons{margin:0 20px}.file-picker.fp-msg{text-align:center}.file-picker.fp-msg .fp-msg-text{max-width:500px;max-height:300px;min-width:200px;padding:40px 20px 10px 20px;overflow:auto;font-size:12px}.file-picker.fp-msg.fp-msg-error .fp-msg-text{padding:40px 20px 10px 20px;font-size:12px}.file-picker .fp-content-error{display:table;width:100%;height:100%;text-align:center}.file-picker .fp-content-error .fp-error{display:table-cell;width:100%;height:100%;padding:40px 20px 10px 20px;font-size:12px;vertical-align:middle}.file-picker .fp-nextpage{clear:both}.file-picker .fp-nextpage .fp-nextpage-loading{display:none}.file-picker .fp-nextpage.loading .fp-nextpage-link{display:none}.file-picker .fp-nextpage.loading .fp-nextpage-loading{display:block;height:100px;padding-top:50px;text-align:center}.fp-select form{padding:20px 20px 0}.fp-select .fp-select-loading{margin-top:20px;text-align:center}.fp-select .fp-hr{width:auto;height:1px;margin:10px 0;clear:both;background-color:#fff;border-bottom:1px solid #bbb}.fp-select table{padding:0 0 10px}.fp-select table .mdl-right{min-width:84px}.fp-select .fp-reflist .mdl-right{vertical-align:top}.fp-select .fp-select-buttons{float:right}.fp-select .fp-info{display:block;padding:1px 20px 0;clear:both}.fp-select .fp-thumbnail{float:left;min-width:110px;min-height:110px;margin:10px 20px 0 0;line-height:110px;text-align:center;background:#fff;border:1px solid #ddd;-webkit-box-shadow:inset 0 0 10px 0 #ccc;-moz-box-shadow:inset 0 0 10px 0 #ccc;box-shadow:inset 0 0 10px 0 #ccc}.fp-select .fp-thumbnail img{padding:3px;margin:10px;vertical-align:middle;border:1px solid #ddd}.fp-select .fp-fileinfo{display:inline-block;*display:inline;margin-top:10px;*zoom:1}.file-picker.fp-select .fp-fileinfo{max-width:240px}.fp-select .fp-fileinfo div{padding-bottom:5px}.file-picker.fp-select .uneditable{display:none}.file-picker.fp-select .fp-select-loading{display:none}.file-picker.fp-select.loading .fp-select-loading{display:block}.file-picker.fp-select.loading form{display:none}.fp-select .fp-dimensions.fp-unknown{display:none}.filemanager-loading{display:none}.jsenabled .filemanager-loading{display:block;margin-top:100px}.filemanager.fm-loading .filemanager-toolbar,.filemanager.fm-loading .fp-pathbar,.filemanager.fm-loading .filemanager-container,.filemanager.fm-loaded .filemanager-loading,.filemanager.fm-maxfiles .fp-btn-add,.filemanager.fm-maxfiles .dndupload-message,.filemanager.fm-noitems .fp-btn-download,.filemanager .fm-empty-container,.filemanager.fm-noitems .filemanager-container .fp-content{display:none}.filemanager .filemanager-updating{display:none;text-align:center}.filemanager.fm-updating .filemanager-updating{display:block;margin-top:37px}.filemanager.fm-updating .fm-content-wrapper,.filemanager.fm-nomkdir .fp-btn-mkdir,.fitem.disabled .filemanager .filemanager-toolbar,.fitem.disabled .filemanager .fp-pathbar,.fitem.disabled .filemanager .fp-restrictions,.fitem.disabled .filemanager .fm-content-wrapper{display:none}.fp-restrictions{text-align:right}.filemanager .fp-navbar{background:#f2f2f2;border:1px solid #bbb;border-bottom:0}.filemanager-toolbar{min-height:22px;padding:5px 8px;overflow:hidden}.fp-pathbar{min-height:20px;padding:5px 8px 1px;border-top:1px solid #bbb}.filemanager .fp-pathbar.empty{display:none}.filepicker-filelist,.filemanager-container{position:relative;min-height:140px;overflow:auto;clear:both;background:#fff;border:1px solid #bbb}.filemanager .fp-content{max-height:472px;min-height:157px;overflow:auto}.filemanager-container,.filepicker-filelist{overflow:hidden}.fitem.disabled .filepicker-filelist,.fitem.disabled .filemanager-container{background-color:#ebebe4}.fitem.disabled .fp-btn-choose{color:#999}.fitem.disabled .filepicker-filelist .filepicker-filename{display:none}.fp-iconview .fp-reficons1{position:absolute;top:0;left:0;z-index:1000;width:100%;height:100%}.fp-iconview .fp-reficons2{position:absolute;top:0;left:0;z-index:1001;width:100%;height:100%}.fp-iconview .fp-file.fp-hasreferences .fp-reficons1{background:url('[[pix:theme|fp/link]]') no-repeat;background-position:bottom right}.fp-iconview .fp-file.fp-isreference .fp-reficons2{background:url('[[pix:theme|fp/alias]]') no-repeat;background-position:bottom left}.filemanager .fp-iconview .fp-file.fp-originalmissing .fp-thumbnail img{display:none}.filemanager .fp-iconview .fp-file.fp-originalmissing .fp-thumbnail{background:url([[pix:s/dead]]) no-repeat;background-position:center center}.filemanager .yui3-datatable table{width:100%;border:0 solid #bbb}.filemanager .yui3-datatable-header{color:#555!important;background:#fff!important;border-bottom:1px solid #ccc!important;border-left:0 solid #fff!important}.filemanager .yui3-datatable-odd .yui3-datatable-cell{background-color:#f6f6f6!important;border-left:0 solid #f6f6f6}.filemanager .yui3-datatable-even .yui3-datatable-cell{background-color:#fff!important;border-left:0 solid #fff}.filemanager .fp-filename-icon.fp-hasreferences .fp-reficons1{position:absolute;top:8px;left:17px;z-index:1000;width:100%;height:100%;background:url('[[pix:theme|fp/link_sm]]') no-repeat 0 0}.filemanager .fp-filename-icon.fp-isreference .fp-reficons2{position:absolute;top:9px;left:-6px;z-index:1001;width:100%;height:100%;background:url('[[pix:theme|fp/alias_sm]]') no-repeat 0 0}.filemanager .fp-contextmenu{display:none}.filemanager .fp-iconview .fp-folder.fp-hascontextmenu .fp-contextmenu{position:absolute;right:7px;bottom:5px;display:block}.filemanager .fp-treeview .fp-folder.fp-hascontextmenu .fp-contextmenu,.filemanager .fp-tableview .fp-folder.fp-hascontextmenu .fp-contextmenu{position:absolute;top:6px;left:14px;display:inline;margin-right:-20px}.dir-rtl .filemanager .fp-iconview .fp-folder.fp-hascontextmenu .fp-contextmenu{right:inherit;left:7px}.dir-rtl .filemanager .fp-treeview .fp-folder.fp-hascontextmenu .fp-contextmenu,.dir-rtl .filemanager .fp-tableview .fp-folder.fp-hascontextmenu .fp-contextmenu{right:16px;left:inherit;margin-right:0}.filepicker-filelist .filepicker-container,.filemanager.fm-noitems .fm-empty-container{position:absolute;top:10px;right:10px;bottom:10px;left:10px;display:block;padding-top:85px;text-align:center;border:2px dashed #bbb}.filepicker-filelist .dndupload-target,.filemanager-container .dndupload-target{position:absolute;top:10px;right:10px;bottom:10px;left:10px;padding-top:85px;text-align:center;background:#fff;border:2px dashed #fb7979;-webkit-box-shadow:0 0 0 10px #fff;-moz-box-shadow:0 0 0 10px #fff;box-shadow:0 0 0 10px #fff}.filepicker-filelist.dndupload-over .dndupload-target,.filemanager-container.dndupload-over .dndupload-target{position:absolute;top:10px;right:10px;bottom:10px;left:10px;padding-top:85px;text-align:center;background:#fff;border:2px dashed #6c8cd3}.dndupload-message{display:none}.dndsupported .dndupload-message{display:inline}.dnduploadnotsupported-message{display:none}.dndnotsupported .dnduploadnotsupported-message{display:inline}.dndupload-target{display:none}.dndsupported .dndupload-ready .dndupload-target{display:block}.dndupload-uploadinprogress{display:none;text-align:center}.dndupload-uploading .dndupload-uploadinprogress{display:block}.dndupload-arrow{position:absolute;top:5px;width:100%;height:80px;margin-left:-28px;background:url([[pix:theme|fp/dnd_arrow]]) center no-repeat}.fitem.disabled .filepicker-container,.fitem.disabled .fm-empty-container{display:none}.dndupload-progressbars{display:none;padding:10px}.dndupload-inprogress .dndupload-progressbars{display:block}.dndupload-inprogress .fp-content{display:none}.filemanager.fm-noitems .dndupload-inprogress .fm-empty-container{display:none}.filepicker-filelist.dndupload-inprogress .filepicker-container{display:none}.filepicker-filelist.dndupload-inprogress a{display:none}.filemanager.fp-select .fp-select-loading{display:none}.filemanager.fp-select.loading .fp-select-loading{display:block}.filemanager.fp-select.loading form{display:none}.filemanager.fp-select.fp-folder .fp-license,.filemanager.fp-select.fp-folder .fp-author,.filemanager.fp-select.fp-file .fp-file-unzip,.filemanager.fp-select.fp-folder .fp-file-unzip,.filemanager.fp-select.fp-file .fp-file-zip,.filemanager.fp-select.fp-zip .fp-file-zip{display:none}.filemanager.fp-select .fp-file-setmain{display:none}.filemanager.fp-select.fp-cansetmain .fp-file-setmain{display:inline-block;*display:inline;*zoom:1}.filemanager .fp-mainfile .fp-filename{font-weight:bold}.filemanager.fp-select.fp-folder .fp-file-download{display:none}.fm-operation{font-weight:bold}.filemanager.fp-select .fp-original.fp-unknown,.filemanager.fp-select .fp-original .fp-originloading{display:none}.filemanager.fp-select .fp-original.fp-loading .fp-originloading{display:inline}.filemanager.fp-select .fp-reflist.fp-unknown,.filemanager.fp-select .fp-reflist .fp-reflistloading{display:none}.filemanager.fp-select .fp-refcount{max-width:265px}.filemanager.fp-select .fp-reflist.fp-loading .fp-reflistloading{display:inline}.filemanager.fp-select .fp-reflist .fp-value{max-width:265px;max-height:75px;padding:8px 7px;margin:0;overflow:auto;background:#f9f9f9;border:1px solid #bbb}.filemanager.fp-select .fp-reflist .fp-value li{padding-bottom:7px}.filemanager.fp-mkdir-dlg{text-align:center}.filemanager.fp-mkdir-dlg .fp-mkdir-dlg-text{margin:20px;text-align:left}.dir-rtl .filemanager .fp-mkdir-dlg p{text-align:right}.filemanager.fp-dlg{text-align:center}.filemanager.fp-dlg .fp-dlg-text{max-width:340px;max-height:300px;min-width:200px;padding:0 10px;margin:40px 20px 20px;overflow:auto;font-size:12px;line-height:22px}.file-picker div.bd{text-align:left}.dir-rtl .file-picker div.bd,.dir-rtl .file-picker .fp-pathbar,.dir-rtl .file-picker .fp-list,.dir-rtl #filemenu .yuimenuitemlabel,.dir-rtl .filemanager-container .yui3-skin-sam .yui3-datatable-header{text-align:right}.dir-rtl .filepicker .yui-layout-unit-left{left:500px}.dir-rtl .filepicker .yui-layout-unit-center{left:0}.allcoursegrades{width:100%;padding:4px 0 5px 0;text-align:right}.path-grade-edit .buttons{text-align:center}.path-grade-edit-tree .idnumber{margin-left:15px}.path-grade-edit-tree .movetarget{position:relative;width:80px;height:16px}.path-grade-edit-tree ul#grade_tree{width:auto}.path-grade-edit-tree ul#grade_tree li{list-style:none}.path-grade-edit-tree ul#grade_tree li.category{margin-bottom:6px}.path-grade-edit-tree .iconsmall{margin-left:4px}#grade-report-toggles{text-align:center}#grade-aggregation-help dt{margin-top:15px}#grade-aggregation-help dd.example{margin-top:7px}#grade-aggregation-help code{display:block;margin-top:7px}.gradeexportlink{padding:2em;text-align:center}.gradetreebox{margin-top:10px;overflow-x:auto;overflow-y:hidden}.gradetreebox table{width:100%;font-size:.8em}.gradetreebox td.colspan,.gradetreebox tr.category .cell{background-color:#DDD}.gradetreebox th.actions{width:105px;white-space:nowrap}.gradetreebox td.name{white-space:nowrap}.gradetreebox td.name h4{display:inline}.gradetreebox td.range{white-space:nowrap}.gradetreebox span.actionlink{color:blue}.gradetreebox span.actionlink:hover{text-decoration:underline;cursor:pointer}.gradetreebox img.iconsmall{margin-left:4px}.gradetreebox img.icon{margin-right:5px}.gradetreebox #gradetreesubmit{margin-bottom:1em;text-align:center}.gradetreebox .hidden{display:none}#page-grade-grading-manage #activemethodselector{margin-bottom:1em;text-align:center}#page-grade-grading-manage #activemethodselector select{margin:0 1em}#page-grade-grading-manage .actions{text-align:center}#page-grade-grading-manage .action{display:inline-block;width:150px;padding:.5em;margin:.5em;text-align:center;background-color:#eee;border:2px solid #ccc;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-manage .action:hover{text-decoration:none;background-color:#f6f6f6}#page-grade-grading-manage #actionresultmessagebox{position:relative;width:60%;padding:.5em;margin:1em auto;text-align:center;background-color:#d2ebff;border:2px solid #CCC;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-manage #actionresultmessagebox span{position:absolute;top:-1.2em;right:0;font-size:80%;color:#666}#page-grade-grading-manage .definition-name .status{padding:.25em;font-size:60%;font-weight:normal;text-transform:uppercase;border:1px solid #EEE;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-manage .definition-name .status.ready{background-color:#e7f1c3;border-color:#aea}#page-grade-grading-manage .definition-name .status.draft{background-color:#f3f2aa;border-color:#ee2}#page-grade-grading-manage .definition-preview{width:50%;padding:1em;margin:1em auto;border:1px solid #EEE}#page-grade-grading-pick .template-name{padding:3px;clear:both;background-color:#f6f6f6}#page-grade-grading-pick .template-name .type{padding:.25em;font-size:60%;font-weight:normal;text-transform:uppercase;border:1px solid #eee;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}#page-grade-grading-pick .template-name .type.shared{background-color:#e7f1c3;border-color:#aea}#page-grade-grading-pick .template-name .type.ownform{background-color:#d2ebff;border-color:#ace}#page-grade-grading-pick .template-description{padding:0 2em 0 0;margin-right:51%;margin-bottom:1em}#page-grade-grading-pick .template-preview{float:right;width:50%;padding:1em;margin-bottom:1em;border:1px solid #EEE}#page-grade-grading-pick .template-actions{padding:0 2em 0 0;margin-right:51%;margin-bottom:1em}#page-grade-grading-pick .template-actions .action{display:inline-block;padding:.25em;margin:.25em;border:2px solid transparent}#page-grade-grading-pick .template-actions .action.pick{background-color:#EEE;border:2px solid #CCC;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}#page-grade-grading-pick .template-actions .action:hover{text-decoration:none;background-color:#f6f6f6;border:2px solid #CCC;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}#page-grade-grading-pick .template-actions .action .action-text{display:inline}#page-grade-grading-pick .template-actions .action .action-icon{margin:0 3px}#page-grade-grading-pick .template-preview-confirm{width:50%;padding:1em;margin:1em auto;border:1px solid #EEE}#page-grade-grading-pick .singlebutton{clear:both}table#user-grades tr.avg td.cell{font-weight:700;color:#00008b;background-color:#efefff}table#user-grades tr td.overridden{background-color:#f3e4c0}table#user-grades tr.odd td.overridden{background-color:#efd9a4}table#user-grades tr td.ajaxoverridden{background-color:#ffe3a0}table#user-grades tr.odd td.ajaxoverridden{background-color:#ffda83}table#user-grades tr.even td.excluded{background-color:#eabfff}table#user-grades tr.odd td.excluded{background-color:#e5afff}table#user-grades tr.groupavg td.cell{font-weight:700;color:#006400;background-color:#efffef}table#user-grades td.cat,table#user-grades td.course{font-weight:700}.path-grade-report-grader #overDiv table{margin:0}.path-grade-report-grader #overDiv table td.feedback{border:0}.path-grade-report-grader #overDiv .feedback{font-size:10.5px;font-weight:400;background-color:#ABF}.path-grade-report-grader #overDiv .caption{font-size:10.5px;font-weight:700;color:#CCF;background-color:#56C}.path-grade-report-grader #overDiv .intersection{font-size:10.5px;font-weight:400;color:#000;background-color:#ABF}.path-grade-report-grader #overDiv .intersectioncaption{font-weight:700;color:#CCF;background-color:#56C}.path-grade-report-grader div.gradeparent,table#user-grades td.ajax{text-align:left}.path-grade-report-grader.dir-rtl div.gradeparent,.dir-rtl table#user-grades td.ajax{text-align:right}table#user-grades td,table#user-grades th{text-align:right}table#user-grades .courseitem{text-align:right;white-space:nowrap}table#user-grades th.category,table#user-grades th#studentheader,table#user-grades th.user{text-align:left}.dir-rtl table#user-grades th.category,.dir-rtl table#user-grades th#studentheader,.dir-rtl table#user-grades th.user{text-align:right}div.gradertoggle{display:inline;margin-left:20px}table#user-grades .userpic{margin-right:10px}table#user-grades .quickfeedback{margin-left:10px;border:1px dashed #000}.dir-rtl table#user-grades .quickfeedback{margin-right:10px;margin-left:0}.path-grade-report-grader #siteconfiglink{text-align:right}table#user-grades .datesubmitted{font-size:10.5px}.path-grade-report-grader span.inclusion-links{margin:0 5px 0 10px}.path-grade-report-grader th.user img.userpicture{margin-right:.5em}.path-grade-report-grader.dir-rtl th.user img.userpicture{margin-left:.5em}.path-grade-report-grader a.quickedit{display:block;float:right;margin:.1em 0 0;clear:none;font-size:9px;line-height:1em;background-color:transparent}.path-grade-report-grader a.quickedit2{display:block;float:right;margin:1.3em 0 0;clear:none;background-color:transparent}.path-grade-report-grader table#quick_edit{margin:0 auto;border:1px solid #cecece}.path-grade-report-grader table#quick_edit td{padding:5px;margin:0;text-align:left;vertical-align:middle;border:1px solid #cecece}.path-grade-report-grader table#quick_edit td img{padding:0;vertical-align:middle;border:3px double #cecece}.path-grade-report-grader table#quick_edit td.fullname{padding-left:5px;border-left:0}.path-grade-report-grader table#quick_edit td.picture{border-right:0}.path-grade-report-grader table#quick_edit td.finalgrade input{width:5em}.path-grade-report-grader h1{clear:both;text-align:center}.path-grade-report-grader input.center{margin:10px auto 0}.path-grade-report-grader .lefttbody{width:auto;vertical-align:middle}.path-grade-report-grader .left_scroller{float:left;clear:none}.path-grade-report-grader .left_scroller #fixed_column .heading th.header,.path-grade-report-grader .left_scroller #fixed_column td,.path-grade-report-grader .left_scroller #fixed_column th{height:4em}.path-grade-report-grader .left_scroller #fixed_column td.controls{height:2em}.path-grade-report-grader.dir-rtl .left_scroller{float:right}.path-grade-report-grader .right_scroller{width:auto;overflow-x:scroll;clear:none}.path-grade-report-grader .right_scroller tr.heading_name_row th,.path-grade-report-grader .right_scroller table#user-grades td.grade{height:4em}.path-grade-report-grader .right_scroller .path-grade-report-grader .left_scroller .topleft,.path-grade-report-grader .right_scroller tr.avg td,.path-grade-report-grader .right_scroller tr.groupavg,.path-grade-report-grader .right_scroller tr.controls_row,.path-grade-report-grader .right_scroller div.right_scroller tr{height:2em}table#fixed_column,table#user-grades,table#fixed_column th,table#fixed_column td,table#user-grades td,table#user-grades th,table#user-grades input{padding:0 2px;margin:0;font-size:10px;vertical-align:middle}.path-grade-report-grader form td.excluded{color:#b94a48}.path-grade-report-grader .excludedfloater{float:left;font-size:9px;font-weight:700;color:#b94a48}.path-grade-report-grader span.gradepass{color:#298721}.path-grade-report-grader span.gradefail{color:#890d0d}.path-grade-report-grader .gradeweight{font-weight:700;color:#461d7c}.path-grade-report-grader td select{padding:0;font-size:100%}.path-grade-report-grader .right_scroller td select{font-size:11.9px}.path-grade-report-grader .grade_icons img.ajax{float:right}.path-grade-report-grader .gradestable th.user,.path-grade-report-grader .gradestable th.range,.path-grade-report-grader .flexible th,.path-grade-report-grader .flexible td,.path-grade-report-grader .flexible th a,.path-grade-report-grader .flexible td a,.path-grade-report-grader .gradestable th.range,.path-grade-report-grader th,.path-grade-report-grader td{white-space:nowrap}table#user-grades td.vmarked{background-color:#fc3}table#user-grades td.hmarked{background-color:#ff9}table#user-grades td.hmarked.vmarked{background-color:#fc9}.path-grade-report-grader .gradeparent{overflow:auto}table#fixed_column tr.controls td,table#user-grades tr.controls td,.path-grade-report-grader table tr.avg,.path-grade-report-grader table tr.avg:hover{background-color:#d9edf7}.path-grade-report-grader table th.user,.path-grade-report-grader table td.userfield{text-align:left}.path-grade-report-grader.dir-rtl table th.user,.path-grade-report-grader.dir-rtl table td.userfield{text-align:right}.path-grade-report-grader .usersuspended a:link,.path-grade-report-grader .usersuspended a:visited{color:#999}.path-grade-report-grader table th.usersuspended img.usersuspendedicon{margin-left:.45em;vertical-align:text-bottom}.path-grade-report-grader .yui3-overlay{left:0;padding:2px 5px;font-size:.7em;background-color:#ffee69;border-color:#d4c237 #a6982b #a6982b;border-style:solid;border-width:1px}.path-grade-report-grader .yui3-overlay .fullname{font-weight:bold;color:#5f3e00}.path-grade-report-grader .yui3-overlay .itemname{font-weight:bold;color:#194f3e}.path-grade-report-grader .yui3-overlay .feedback{color:#5f595e}.path-grade-report-grader #tooltipPanel{text-align:left}.path-grade-report-grader .yui3-overlay a.container-close{margin-top:-3px}.path-grade-report-grader #hiddentooltiproot,.tooltipDiv{display:none}.gradingform_rubric.editor .criteria .definition textarea,.gradingform_rubric.editor .criteria .scorevalue input{width:auto}.gradingform_rubric.editor .criteria .scorevalue input{float:left}.message-discussion-noframes h1{font-size:1em}.message-discussion-noframes #userinfo .commands,.message .noframesjslink,.message .link{font-size:11.9px}.message .heading{font-size:1em;font-weight:bold}.message .author{font-weight:bold}.message .time{font-style:italic}#page-message-user .commands span{font-size:.7em}#page-message-user .name{font-size:1.1em;font-weight:bold}table.message_search_results td{border-color:#ddd}.message .time,.message.me .author{color:#999}.message.other .author{color:#88c}#page-message-messages{padding:10px}#page-message-send .notifysuccess{padding:1px}#page-message-send td.fixeditor{text-align:center}.message .note{padding:10px}table.message .searchresults td{padding:5px}.message .contactselector{float:left;width:24%}.message .contactselector .contact{text-align:left}.message .contactselector .messageselecteduser{font-weight:bold}.message .contactselector .paging{position:relative;z-index:1}.message .messagearea{float:right;width:74%;min-height:200px;padding-left:1%;border-left:1px solid #d3d3d3}.message .messagearea .messagehistorytype{padding-bottom:20px;clear:both}.message .messagearea .messagehistory .message_user_pictures{margin-right:auto;margin-left:auto}.message .messagearea .messagehistory .message_user_pictures #user1{width:200px;vertical-align:top}.message .messagearea .messagehistory .message_user_pictures #user2{width:200px;vertical-align:top}.message .messagearea .messagehistory .message_user_pictures .useractionlinks{font-size:.9em}.message .messagearea .messagehistory .heading{width:100%;clear:both}.message .messagearea .messagehistory .left{float:left;width:50%;padding-bottom:10px;clear:both}.message .messagearea .messagehistory .right{float:right;width:50%;padding-bottom:10px;clear:both}.message .messagearea .messagehistory .notification{padding:10px;margin-top:5px;background-color:#eee}.message .messagearea .messagesend{padding-top:20px;clear:both}.message .messagearea .messagesend .messagesendbox{width:100%}.message .messagearea .messagesend fieldset{padding:0;margin:0}.message .messagearea .messagerecent{width:100%;text-align:left}.message .messagearea .messagerecent .singlemessage{padding:10px;border-bottom:1px solid #d3d3d3}.message .messagearea .messagerecent .singlemessage .otheruser span{padding:5px}.message .messagearea .messagerecent .singlemessage .messagedate{float:right}.message .hiddenelement{display:none}.message .visible{display:inline}.message #usergroupselector.fieldset,.message #viewing{width:100%}.messagesearchresults{margin-bottom:40px}.messagesearchresults td{padding:0 10px 0 20px}.messagesearchresults td span{white-space:nowrap}.messagesearchresults td img.userpicture{padding-right:.45em;vertical-align:text-bottom}.dir-rtl .messagesearchresults td img.userpicture{padding-right:0;padding-left:.45em}.messagesearchresults td span img{padding:0 0 0 .45em;vertical-align:text-bottom}.dir-rtl .messagesearchresults td span img{padding:0 .45em 0 0}#newmessageoverlay{position:fixed;right:0;bottom:0;padding:20px;background-color:#d3d3d3;border:1px solid black}#newmessageoverlay #usermessage{padding:10px}.questionbank h2{margin-top:0}.questioncategories h3{margin-top:0}#chooseqtypebox{margin-top:1em}#chooseqtype h3{margin:0 0 .3em}#chooseqtype .instruction{display:none}#chooseqtype .fakeqtypes{border-top:1px solid silver}#chooseqtype .qtypeoption{margin-bottom:.5em}#chooseqtype label{display:block}#chooseqtype .qtypename img{padding:0 .3em}#chooseqtype .qtypename{display:inline-table;width:16em}#chooseqtype .qtypesummary{display:block;margin:0 2em}#chooseqtype .submitbuttons{margin:.7em 0;text-align:center}#qtypechoicecontainer{display:none}#qtypechoicecontainer_c.yui-panel-container.shadow .underlay{background:0}#qtypechoicecontainer.yui-panel .hd{letter-spacing:1px;color:#333;text-shadow:1px 1px 1px #fff;background-color:#ebebeb;background-image:-moz-linear-gradient(top,#fff,#ccc);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ccc));background-image:-webkit-linear-gradient(top,#fff,#ccc);background-image:-o-linear-gradient(top,#fff,#ccc);background-image:linear-gradient(to bottom,#fff,#ccc);background-repeat:repeat-x;border:1px solid #ccc;border-bottom:1px solid #bbb;-webkit-border-top-right-radius:10px;border-top-right-radius:10px;-webkit-border-top-left-radius:10px;border-top-left-radius:10px;-moz-border-radius-topright:10px;-moz-border-radius-topleft:10px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffcccccc',GradientType=0)}#qtypechoicecontainer{font-size:12px;color:#333;background:#f2f2f2;border:1px solid #ccc;border-top:0 none;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:5px 5px 20px 0 #666;-moz-box-shadow:5px 5px 20px 0 #666;box-shadow:5px 5px 20px 0 #666}#chooseqtype{width:40em}#chooseqtypehead h3{margin:0;font-weight:normal}#chooseqtype .qtypes{position:relative;padding:.24em 0;border-bottom:1px solid #bbb}#chooseqtype .qtypeoption{padding:.3em .3em .3em 1.6em;margin-bottom:0}#chooseqtype .qtypeoption img{padding-right:.5em;padding-left:1em;vertical-align:text-bottom}#chooseqtype .selected{background-color:#fff;-webkit-box-shadow:0 0 10px 0 #ccc;-moz-box-shadow:0 0 10px 0 #ccc;box-shadow:0 0 10px 0 #ccc}#chooseqtype .instruction,#chooseqtype .qtypesummary{position:absolute;top:0;right:0;bottom:0;left:60%;display:none;padding:1.5em 1.6em;margin:0;overflow-y:auto;background-color:#fff}#chooseqtype .instruction,#chooseqtype .selected .qtypesummary{display:block}#categoryquestions{margin:0}#categoryquestions td,#categoryquestions th{padding:0 .2em}#categoryquestions th{font-weight:normal;text-align:left}#categoryquestions .checkbox{padding-left:20px}.dir-rtl #categoryquestions th{text-align:right}.questionbank .singleselect{margin:0}#combinedfeedbackhdr div.fhtmleditor{padding:0}#combinedfeedbackhdr div.fcheckbox{margin-bottom:1em}#multitriesheader div.fitem_feditor{margin-top:1em}#multitriesheader div.fitem_fgroup{margin-bottom:1em}#multitriesheader div.fitem_fgroup fieldset.felement label{margin-right:.3em;margin-left:.3em}body.path-question-type .fitem_fgroup .accesshide{position:static;left:0;padding-right:.3em;font:inherit}.que{margin:0 auto 1.8em auto;clear:left;text-align:left}.dir-rtl .que{text-align:right}.que .info{float:left;width:7em;padding:.5em;margin-bottom:1.8em;background-color:#eee;border:1px solid #dcdcdc;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.que h2.no{margin:0;font-size:.8em;line-height:1}.que span.qno{font-size:1.5em;font-weight:bold}.que .info>div{margin-top:.7em;font-size:.8em}.que .info .questionflag.editable{cursor:pointer}.que .info .editquestion img,.que .info .questionflag img,.que .info .questionflag input{vertical-align:bottom}.que .content{margin:0 0 0 8.5em}.que .formulation,.que .outcome,.que .comment{padding:8px 35px 8px 14px;margin-bottom:20px;color:#c09853;text-shadow:0 1px 0 rgba(255,255,255,0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.que .formulation{color:#3a87ad;color:#333;background-color:#d9edf7;border-color:#bce8f1}.formulation input[type="text"],.formulation select{width:auto}.path-mod-quiz input[size]{width:auto}.que .comment{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.que .history{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.que .history blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.que .ablock{margin:.7em 0 .3em 0}.que .im-controls{margin-top:.5em;text-align:left}.dir-rtl .que .im-controls{text-align:right}.que .specificfeedback,.que .generalfeedback,.que .rightanswer,.que .im-feedback,.que .feedback,.que p{margin:0 0 .5em}.que .qtext{margin-bottom:1.5em}.que .correctness{display:inline-block;padding:2px 4px;font-size:11.844px;font-weight:bold;line-height:14px;color:#fff;text-shadow:0 -1px 0 rgba(0,0,0,0.25);white-space:nowrap;vertical-align:baseline;background-color:#999;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.que .correctness:empty{display:none}.que .correctness-important{background-color:#b94a48}.que .correctness-important[href]{background-color:#953b39}.que .correctness-warning{background-color:#f89406}.que .correctness-warning[href]{background-color:#c67605}.que .correctness-success{background-color:#468847}.que .correctness-success[href]{background-color:#356635}.que .correctness-info{background-color:#3a87ad}.que .correctness-info[href]{background-color:#2d6987}.que .correctness-inverse{background-color:#333}.que .correctness-inverse[href]{background-color:#1a1a1a}.que .correctness.correct{background-color:#468847}.que .correctness.partiallycorrect{background-color:#f89406}.que .correctness.notanswered,.que .correctness.incorrect{background-color:#b94a48}.que .validationerror{color:#b94a48}.formulation .correct{background-color:#dff0d8}.formulation .partiallycorrect{background-color:#fcf8e3}.formulation .incorrect{background-color:#f2dede}.formulation select.correct,.formulation input.correct{color:#468847;background-color:#dff0d8;border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.correct:focus,.formulation input.correct:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #7aba7b}.formulation select.partiallycorrect,.formulation input.partiallycorrect{color:#c09853;background-color:#fcf8e3;border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.partiallycorrect:focus,.formulation input.partiallycorrect:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #dbc59e}.formulation select.incorrect,.formulation input.incorrect{color:#b94a48;background-color:#f2dede;border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.formulation select.incorrect:focus,.formulation input.incorrect:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #d59392}.que .grading,.que .comment,.que .commentlink,.que .history{margin-top:.5em}.que .history h3{margin:0 0 .2em;font-size:1em}.que .history table{width:100%;margin:0}.que .history .current{font-weight:bold}.que .questioncorrectnessicon{vertical-align:text-bottom}.que input.questionflagimage{padding-right:3px}.dir-rtl .que input.questionflagimage{padding-right:0;padding-left:3px}.importerror{margin-top:10px;border-bottom:1px solid #555}.mform .que.comment .fitemtitle{width:20%}#page-question-preview #techinfo{margin:1em 0}.dir-rtl #chooseqtype .instruction,.dir-rtl #chooseqtype .qtypesummary{right:60%;left:0;border-right:1px solid grey;border-left:0}#page-mod-quiz-edit .questionbankwindow div.header{padding:3px;padding:2px 10px 2px 10px;margin:0 -10px 0 -10px;color:#444;text-shadow:none;background:transparent;-webkit-border-top-right-radius:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;border-top-left-radius:4px;-moz-border-radius-topright:4px;-moz-border-radius-topleft:4px}#page-mod-quiz-edit .questionbankwindow div.header a:link,#page-mod-quiz-edit .questionbankwindow div.header a:visited{color:#08c}#page-mod-quiz-edit .questionbankwindow div.header a:hover{color:#005580}#page-mod-quiz-edit .questionbankwindow div.header .title{color:#333}#page-mod-quiz-edit div.container div.generalbox{padding:1.5em;background-color:transparent}#page-mod-quiz-edit .categoryinfo{background-color:#fff;border-bottom:0}#page-mod-quiz-edit div.questionbank .categoryquestionscontainer,#page-mod-quiz-edit div.questionbank .categorysortopotionscontainer,#page-mod-quiz-edit div.questionbank .categorypagingbarcontainer,#page-mod-quiz-edit div.questionbank .categoryselectallcontainer{padding:0 0 1.5em 0}#page-mod-quiz-edit div.questionbank .categorypagingbarcontainer{padding:1em;margin:0 -1.2em;background-color:transparent;border-top:0;border-bottom:0}#page-mod-quiz-edit div.questionbank .categoryquestionscontainer{margin:0 -1.2em -1em -1.2em}#page-mod-quiz-edit div.question div.content div.questioncontrols{background-color:#fff}#page-mod-quiz-edit div.question div.content div.points{padding-bottom:.5em;margin-top:-0.5em;background-color:#fff;border:0}#page-mod-quiz-edit div.question div.content div.points label{display:inline-block}#page-mod-quiz-edit div.quizpage .pagecontent .pagestatus{background-color:#fff}#page-mod-quiz-edit .quizpagedelete,#page-mod-quiz-edit .quizpagedelete img{background-color:transparent}#page-mod-quiz-edit div.quizpage .pagecontent{overflow:hidden;border:1px solid #ddd;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}#page-mod-quiz-edit .modulespecificbuttonscontainer{width:220px}.questionbankwindow .module{width:auto}#page-mod-quiz-edit div.editq div.question div.content{overflow:hidden;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.path-mod-quiz .statedetails{display:block;font-size:.9em}a#hidebankcmd{color:#08c}.que.shortanswer .answer{padding:0}.que label{display:inline}.userprofile .fullprofilelink{margin:10px;text-align:center}.userprofile .description{margin-bottom:20px}.userprofile dl.list{*zoom:1}.userprofile dl.list:before,.userprofile dl.list:after{display:table;line-height:0;content:""}.userprofile dl.list:after{clear:both}.userprofile dl.list dt{float:left;width:180px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.userprofile dl.list dd{margin-left:200px}.user-box{float:left;width:115px;height:160px;margin:8px;clear:none;text-align:center}.userlist .main .action-icon img{vertical-align:middle}.userlist #showall{margin:10px 0}.userlist .buttons{text-align:center}.userlist .buttons label{padding:0 3px}.userlist table#participants{text-align:center}.userlist table#participants td,.userlist table#participants th{padding:4px;text-align:left;vertical-align:middle}.userlist table.controls{width:100%}.userlist table.controls tr{vertical-align:top}.userlist table.controls td.right,.userlist table.controls td.left{padding:4px}.userlist table.controls .right{text-align:right}.userinfobox{width:100%;padding:10px;border:1px solid;border-collapse:separate}.userinfobox .left,.userinfobox .side{width:100px;vertical-align:top}.userinfobox .userpicture{width:100px;height:100px}.userinfobox .content{vertical-align:top}.userinfobox .links{width:100px;padding:5px;vertical-align:bottom}.userinfobox .links a{display:block}.userinfobox .list td{padding:3px}.userinfobox .username{padding-bottom:20px;font-weight:bold}.userinfobox td.label{font-weight:bold;text-align:right;white-space:nowrap;vertical-align:top}.groupinfobox{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.groupinfobox blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.groupinfobox .left{width:100px;padding:10px;vertical-align:top}.course-participation #showall{margin:10px 0;text-align:center}#user-policy .noticebox{width:80%;height:250px;margin-right:auto;margin-bottom:10px;margin-left:auto;text-align:center}#user-policy #policyframe{width:100%;height:100%}.iplookup #map{margin:auto}.userselector select{width:100%}.userselector div{margin-top:.2em}.userselector div label{margin-right:.3em}.userselector .userselector-infobelow{font-size:.8em}#userselector_options{padding:.3em 0}#userselector_options .collapsibleregioncaption{font-weight:bold}#userselector_options p{margin:.2em 0;text-align:left}.dir-rtl #userselector_options p{text-align:right}#page-user-profile .messagebox{margin-right:auto;margin-left:auto;text-align:center}#page-course-view-weeks .messagebox{margin-right:auto;margin-left:auto;text-align:center}.dir-rtl .descriptionbox{margin-right:110px;margin-left:0}.dir-rtl .userlist table#participants td,.dir-rtl .userlist table#participants th{text-align:right}.dir-rtl .userlist table#participants{margin:0 auto}#page-my-index.dir-rtl .block h3.main{text-align:right}/*!
  * Bootstrap v2.3.0
  *
  * Copyright 2012 Twitter, Inc
index 49758e2..821ba4d 100644 (file)
@@ -28,6 +28,7 @@ require_once($CFG->libdir.'/gdlib.php');
 require_once($CFG->dirroot.'/user/edit_form.php');
 require_once($CFG->dirroot.'/user/editlib.php');
 require_once($CFG->dirroot.'/user/profile/lib.php');
+require_once($CFG->dirroot.'/user/lib.php');
 
 //HTTPS is required in this page when $CFG->loginhttps enabled
 $PAGE->https_required();
@@ -177,8 +178,6 @@ $email_changed = false;
 
 if ($usernew = $userform->get_data()) {
 
-    add_to_log($course->id, 'user', 'update', "view.php?id=$user->id&course=$course->id", '');
-
     $email_changed_html = '';
 
     if ($CFG->emailchangeconfirmation) {
@@ -206,15 +205,15 @@ if ($usernew = $userform->get_data()) {
         $usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, $personalcontext, 'user', 'profile', 0);
     }
 
-    $DB->update_record('user', $usernew);
-
-    // pass a true $userold here
-    if (! $authplugin->user_update($user, $usernew)) {
-        // auth update failed, rollback for moodle
-        $DB->update_record('user', $user);
+    // Pass a true old $user here.
+    if (!$authplugin->user_update($user, $usernew)) {
+        // Auth update failed.
         print_error('cannotupdateprofile');
     }
 
+    // Update user with new profile data.
+    user_update_user($usernew, false);
+
     //update preferences
     useredit_update_user_preference($usernew);
 
@@ -259,7 +258,6 @@ if ($usernew = $userform->get_data()) {
 
     // reload from db
     $usernew = $DB->get_record('user', array('id'=>$user->id));
-    events_trigger('user_updated', $usernew);
 
     if ($USER->id == $user->id) {
         // Override old $USER session variable if needed
index 9409937..9728bbd 100644 (file)
@@ -29,6 +29,7 @@ require_once($CFG->libdir.'/adminlib.php');
 require_once($CFG->dirroot.'/user/editadvanced_form.php');
 require_once($CFG->dirroot.'/user/editlib.php');
 require_once($CFG->dirroot.'/user/profile/lib.php');
+require_once($CFG->dirroot.'/user/lib.php');
 
 //HTTPS is required in this page when $CFG->loginhttps enabled
 $PAGE->https_required();
@@ -177,20 +178,15 @@ if ($usernew = $userform->get_data()) {
         } else {
             $usernew->password = hash_internal_user_password($usernew->newpassword);
         }
-        $usernew->id = $DB->insert_record('user', $usernew);
-        $usercreated = true;
-        add_to_log($course->id, 'user', 'add', "view.php?id=$usernew->id&course=$course->id", '');
-
+        $usernew->id = user_create_user($usernew, false);
     } else {
         $usernew = file_postupdate_standard_editor($usernew, 'description', $editoroptions, $usercontext, 'user', 'profile', 0);
-        $DB->update_record('user', $usernew);
-        // pass a true $userold here
-        if (! $authplugin->user_update($user, $userform->get_data())) {
-            // auth update failed, rollback for moodle
-            $DB->update_record('user', $user);
+        // Pass a true old $user here.
+        if (!$authplugin->user_update($user, $usernew)) {
+            // Auth update failed.
             print_error('cannotupdateuseronexauth', '', '', $user->auth);
         }
-        add_to_log($course->id, 'user', 'update', "view.php?id=$user->id&course=$course->id", '');
+        user_update_user($usernew, false);
 
         //set new password if specified
         if (!empty($usernew->newpassword)) {
@@ -206,8 +202,6 @@ if ($usernew = $userform->get_data()) {
         if (isset($usernew->suspended) and $usernew->suspended and !$user->suspended) {
             session_kill_user($user->id);
         }
-
-        $usercreated = false;
     }
 
     $usercontext = context_user::instance($usernew->id);
@@ -237,13 +231,6 @@ if ($usernew = $userform->get_data()) {
     // reload from db
     $usernew = $DB->get_record('user', array('id'=>$usernew->id));
 
-    // trigger events
-    if ($usercreated) {
-        events_trigger('user_created', $usernew);
-    } else {
-        events_trigger('user_updated', $usernew);
-    }
-
     if ($createpassword) {
         setnew_password_and_mail($usernew);
         unset_user_preference('create_password', $usernew);
index 0aee6c8..256af0f 100644 (file)
@@ -26,6 +26,7 @@
 require_once('../config.php');
 require_once($CFG->libdir.'/adminlib.php');
 require_once($CFG->dirroot.'/user/editlib.php');
+require_once($CFG->dirroot.'/user/lib.php');
 
 $key = required_param('key', PARAM_ALPHANUM);
 $id  = required_param('id', PARAM_INT);
@@ -60,17 +61,16 @@ if (empty($preferences['newemailattemptsleft'])) {
     cancel_email_update($user->id);
     $user->email = $preferences['newemail'];
 
-    // Detect duplicate before saving
+    // Detect duplicate before saving.
     if ($DB->get_record('user', array('email' => $user->email))) {
         $stremailnowexists = get_string('emailnowexists', 'auth');
         echo $OUTPUT->box($stremailnowexists, 'center');
         echo $OUTPUT->continue_button("$CFG->wwwroot/user/view.php?id=$user->id");
     } else {
-        // update user email
-        $DB->set_field('user', 'email', $user->email, array('id' => $user->id));
+        // Update user email.
         $authplugin = get_auth_plugin($user->auth);
         $authplugin->user_update($olduser, $user);
-        events_trigger('user_updated', $user);
+        user_update_user($user, false);
         $a->email = $user->email;
         $stremailupdatesuccess = get_string('emailupdatesuccess', 'auth', $a);
         echo $OUTPUT->box($stremailupdatesuccess, 'center');
index 737a98a..7ab6c0d 100644 (file)
 /**
  * Creates a user
  *
- * @param object $user user to create
+ * @param stdClass $user user to create
+ * @param bool $updatepassword if true, authentication plugin will update password.
  * @return int id of the newly created user
  */
-function user_create_user($user) {
+function user_create_user($user, $updatepassword = true) {
     global $DB;
 
-    // set the timecreate field to the current time
+    // Set the timecreate field to the current time.
     if (!is_object($user)) {
             $user = (object)$user;
     }
 
-    //check username
+    // Check username.
     if ($user->username !== core_text::strtolower($user->username)) {
         throw new moodle_exception('usernamelowercase');
     } else {
@@ -48,10 +49,10 @@ function user_create_user($user) {
         }
     }
 
-    // save the password in a temp value for later
-    if (isset($user->password)) {
+    // Save the password in a temp value for later.
+    if ($updatepassword && isset($user->password)) {
 
-        //check password toward the password policy
+        // Check password toward the password policy.
         if (!check_password_policy($user->password, $errmsg)) {
             throw new moodle_exception($errmsg);
         }
@@ -63,36 +64,39 @@ function user_create_user($user) {
     $user->timecreated = time();
     $user->timemodified = $user->timecreated;
 
-    // insert the user into the database
+    // Insert the user into the database.
     $newuserid = $DB->insert_record('user', $user);
 
-    // trigger user_created event on the full database user row
-    $newuser = $DB->get_record('user', array('id' => $newuserid));
+    // Create USER context for this user.
+    $usercontext = context_user::instance($newuserid);
 
-    // create USER context for this user
-    context_user::instance($newuserid);
-
-    // update user password if necessary
+    // Update user password if necessary.
     if (isset($userpassword)) {
+        // Get full database user row, in case auth is default.
+        $newuser = $DB->get_record('user', array('id' => $newuserid));
         $authplugin = get_auth_plugin($newuser->auth);
         $authplugin->user_update_password($newuser, $userpassword);
     }
 
-    events_trigger('user_created', $newuser);
-
-    add_to_log(SITEID, 'user', get_string('create'), '/view.php?id='.$newuser->id,
-        fullname($newuser));
+    // Trigger event.
+    $event = \core\event\user_created::create(
+            array(
+                'objectid' => $newuserid,
+                'context' => $usercontext
+                )
+            );
+    $event->trigger();
 
     return $newuserid;
-
 }
 
 /**
  * Update a user with a user object (will compare against the ID)
  *
- * @param object $user the user to update
+ * @param stdClass $user the user to update
+ * @param bool $updatepassword if true, authentication plugin will update password.
  */
-function user_update_user($user) {
+function user_update_user($user, $updatepassword = true) {
     global $DB;
 
     // set the timecreate field to the current time
@@ -111,8 +115,8 @@ function user_update_user($user) {
         }
     }
 
-    // unset password here, for updating later
-    if (isset($user->password)) {
+    // Unset password here, for updating later, if password update is required.
+    if ($updatepassword && isset($user->password)) {
 
         //check password toward the password policy
         if (!check_password_policy($user->password, $errmsg)) {
@@ -126,22 +130,27 @@ function user_update_user($user) {
     $user->timemodified = time();
     $DB->update_record('user', $user);
 
-    // trigger user_updated event on the full database user row
-    $updateduser = $DB->get_record('user', array('id' => $user->id));
+    if ($updatepassword) {
+        // Get full user record.
+        $updateduser = $DB->get_record('user', array('id' => $user->id));
 
-    // if password was set, then update its hash
-    if (isset($passwd)) {
-        $authplugin = get_auth_plugin($updateduser->auth);
-        if ($authplugin->can_change_password()) {
-            $authplugin->user_update_password($updateduser, $passwd);
+        // if password was set, then update its hash
+        if (isset($passwd)) {
+            $authplugin = get_auth_plugin($updateduser->auth);
+            if ($authplugin->can_change_password()) {
+                $authplugin->user_update_password($updateduser, $passwd);
+            }
         }
     }
 
-    events_trigger('user_updated', $updateduser);
-
-    add_to_log(SITEID, 'user', get_string('update'), '/view.php?id='.$updateduser->id,
-        fullname($updateduser));
-
+    // Trigger event.
+    $event = \core\event\user_updated::create(
+            array(
+                'objectid' => $user->id,
+                'context' => context_user::instance($user->id)
+                )
+            );
+    $event->trigger();
 }
 
 /**
diff --git a/user/tests/userlib_test.php b/user/tests/userlib_test.php
new file mode 100644 (file)
index 0000000..9959d0f
--- /dev/null
@@ -0,0 +1,132 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Unit tests for user/lib.php.
+ *
+ * @package    core_user
+ * @category   phpunit
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+global $CFG;
+require_once($CFG->dirroot.'/user/lib.php');
+
+/**
+ * Unit tests for user lib api.
+ *
+ * @package    core_user
+ * @category   phpunit
+ * @copyright  2013 Rajesh Taneja <rajesh@moodle.com>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class core_userliblib_testcase extends advanced_testcase {
+    /**
+     * Test user_update_user.
+     */
+    public function test_user_update_user() {
+        global $DB;
+
+        $this->resetAfterTest();
+
+        // Create user and modify user profile.
+        $user = $this->getDataGenerator()->create_user();
+        $user->firstname = 'Test';
+        $user->password = 'M00dLe@T';
+
+        // Update user and capture event.
+        $sink = $this->redirectEvents();
+        user_update_user($user);
+        $events = $sink->get_events();
+        $sink->close();