Merge branch 'MDL-58356-master' of git://github.com/damyon/moodle
authorAndrew Nicols <andrew@nicols.co.uk>
Thu, 13 Apr 2017 04:10:45 +0000 (12:10 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Thu, 13 Apr 2017 04:10:45 +0000 (12:10 +0800)
204 files changed:
.eslintignore
.stylelintignore
admin/renderer.php
admin/tool/messageinbound/classes/manager.php
admin/tool/mobile/classes/api.php
admin/tool/mobile/classes/external.php
admin/tool/mobile/launch.php
admin/tool/mobile/upgrade.txt
admin/tool/usertours/amd/build/popper.min.js
admin/tool/usertours/amd/build/tour.min.js
admin/tool/usertours/amd/src/popper.js
admin/tool/usertours/amd/src/tour.js
admin/tool/usertours/thirdpartylibs.xml
auth/classes/output/login.php
backup/converter/moodle1/lib.php
backup/converter/moodle1/tests/moodle1_converter_test.php
cache/stores/redis/addinstanceform.php
cache/stores/redis/lang/en/cachestore_redis.php
cache/stores/redis/lib.php
cache/stores/redis/settings.php
cache/stores/redis/version.php
config-dist.php
course/externallib.php
course/tests/externallib_test.php
files/classes/converter.php
files/converter/unoconv/classes/converter.php
files/tests/converter_test.php
filter/mathjaxloader/contrib/a11y/accessibility-menu.js [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/auto-collapse.js [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/collapsible.js [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/explorer.js [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/invalid_keypress.mp3 [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/invalid_keypress.ogg [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathjax-sre.js [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/.htaccess [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/functions/algebra.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/functions/elementary.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/functions/hyperbolic.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/functions/trigonometry.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/mathmaps_ie.js [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/greek-capital.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/greek-mathfonts.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/greek-scripts.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/greek-small.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/greek-symbols.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/hebrew_letters.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/latin-lower-double-accent.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/latin-lower-normal.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/latin-lower-phonetic.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/latin-lower-single-accent.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/latin-mathfonts.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/latin-rest.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/latin-upper-double-accent.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/latin-upper-normal.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/latin-upper-single-accent.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/math_angles.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/math_arrows.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/math_characters.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/math_delimiters.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/math_digits.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/math_geometry.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/math_harpoons.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/math_non_characters.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/math_symbols.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/math_whitespace.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/symbols/other_stars.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/units/energy.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/units/length.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/units/memory.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/units/other.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/units/speed.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/units/temperature.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/units/time.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/units/volume.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/mathmaps/units/weight.json [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/semantic-enrich.js [new file with mode: 0644]
filter/mathjaxloader/contrib/a11y/wgxpath.install.js [new file with mode: 0644]
filter/mathjaxloader/db/upgrade.php
filter/mathjaxloader/db/upgradelib.php [new file with mode: 0644]
filter/mathjaxloader/filter.php
filter/mathjaxloader/readme_moodle.txt
filter/mathjaxloader/settings.php
filter/mathjaxloader/tests/upgradelib_test.php [new file with mode: 0644]
filter/mathjaxloader/thirdpartylibs.xml [new file with mode: 0644]
filter/mathjaxloader/version.php
filter/mediaplugin/styles.css
install/lang/et/error.php
install/lang/et/install.php
install/lang/et/moodle.php
lang/en/mimetypes.php
lang/en/moodle.php
lib/amd/build/ajax.min.js
lib/amd/src/ajax.js
lib/authlib.php
lib/behat/lib.php
lib/classes/filetypes.php
lib/classes/oauth2/client.php
lib/classes/output/icon_system_fontawesome.php
lib/classes/session/redis.php
lib/db/services.php
lib/db/upgrade.php
lib/filestorage/file_storage.php
lib/filestorage/file_system.php
lib/filestorage/file_system_filedir.php
lib/filestorage/stored_file.php
lib/filestorage/tests/file_storage_test.php
lib/filestorage/tests/file_system_filedir_test.php
lib/filestorage/tests/file_system_test.php
lib/filestorage/tests/tgz_packer_test.php
lib/oauthlib.php
lib/phpmailer/README_MOODLE.txt
lib/phpmailer/VERSION
lib/phpmailer/class.phpmailer.php
lib/phpmailer/class.smtp.php
lib/phpmailer/language/phpmailer.lang-de.php
lib/phpmailer/language/phpmailer.lang-es.php
lib/phpmailer/language/phpmailer.lang-ro.php
lib/phpunit/bootstrap.php
lib/searchlib.php
lib/statslib.php
lib/templates/settings_link_page.mustache
lib/tests/grouplib_test.php
lib/thirdpartylibs.xml
lib/upgrade.txt
lib/upgradelib.php
media/player/videojs/styles.css
mod/assign/feedback/file/importziplib.php
mod/assign/lib.php
mod/assign/locallib.php
mod/assign/submission/file/lang/en/assignsubmission_file.php
mod/assign/submission/file/locallib.php
mod/assign/submission/file/tests/behat/file_type_restriction.feature [new file with mode: 0644]
mod/assign/submission/file/tests/locallib_test.php
mod/assign/submission/file/version.php
mod/book/lib.php
mod/chat/classes/external.php
mod/chat/lib.php
mod/choice/lib.php
mod/data/lib.php
mod/feedback/classes/completion.php
mod/feedback/classes/external.php
mod/feedback/classes/external/feedback_completed_exporter.php [new file with mode: 0644]
mod/feedback/db/services.php
mod/feedback/lang/en/deprecated.txt
mod/feedback/lang/en/feedback.php
mod/feedback/lib.php
mod/feedback/show_nonrespondents.php
mod/feedback/tests/behat/behat_mod_feedback.php
mod/feedback/tests/behat/multipleattempt.feature [new file with mode: 0644]
mod/feedback/tests/external_test.php
mod/feedback/upgrade.txt
mod/feedback/version.php
mod/folder/lib.php
mod/forum/backup/moodle2/backup_forum_stepslib.php
mod/forum/backup/moodle2/restore_forum_stepslib.php
mod/forum/classes/output/big_search_form.php
mod/forum/classes/post_form.php
mod/forum/db/tag.php [new file with mode: 0644]
mod/forum/lang/en/forum.php
mod/forum/lib.php
mod/forum/locallib.php
mod/forum/post.php
mod/forum/search.php
mod/forum/templates/big_search_form.mustache
mod/forum/tests/behat/advanced_search.feature
mod/forum/tests/behat/edit_tags.feature [new file with mode: 0644]
mod/forum/tests/behat/forum_subscriptions_availability.feature
mod/forum/tests/behat/forum_subscriptions_management.feature
mod/forum/tests/generator/lib.php
mod/forum/tests/generator_test.php
mod/forum/tests/lib_test.php
mod/forum/version.php
mod/glossary/lib.php
mod/imscp/lib.php
mod/label/lib.php
mod/lesson/lib.php
mod/lti/lib.php
mod/page/lib.php
mod/quiz/lib.php
mod/quiz/styles.css
mod/resource/lib.php
mod/scorm/lib.php
mod/survey/lib.php
mod/url/lib.php
mod/wiki/lib.php
mod/workshop/lib.php
repository/filesystem/lib.php
repository/lib.php
theme/boost/templates/core/settings_link_page.mustache
theme/boost/templates/mod_forum/big_search_form.mustache
theme/bootstrapbase/less/moodle/blocks.less
theme/bootstrapbase/less/moodle/forms.less
theme/bootstrapbase/style/moodle.css
theme/bootstrapbase/templates/block_myoverview/course-event-list-item.mustache
theme/bootstrapbase/templates/block_myoverview/course-event-list.mustache [new file with mode: 0644]
theme/bootstrapbase/templates/block_myoverview/course-item.mustache
theme/bootstrapbase/templates/block_myoverview/course-paging-content-item.mustache [new file with mode: 0644]
theme/bootstrapbase/templates/block_myoverview/course-summary.mustache [new file with mode: 0644]
theme/bootstrapbase/templates/block_myoverview/courses-view-course-item.mustache [new file with mode: 0644]
theme/bootstrapbase/templates/block_myoverview/courses-view.mustache [new file with mode: 0644]
theme/bootstrapbase/templates/block_myoverview/event-list-group.mustache [new file with mode: 0644]
theme/bootstrapbase/templates/block_myoverview/event-list-item.mustache
theme/bootstrapbase/templates/block_myoverview/timeline-view.mustache
version.php

index e62d329..f23715a 100644 (file)
@@ -9,6 +9,7 @@ auth/cas/CAS/
 auth/fc/fcFPP.php
 enrol/lti/ims-blti/
 filter/algebra/AlgParser.pm
+filter/mathjaxloader/contrib/a11y/
 filter/tex/mimetex.*
 lib/editor/atto/yui/src/rangy/js/*.*
 lib/editor/tinymce/plugins/pdw/tinymce/
index 8c3d147..02e5607 100644 (file)
@@ -10,6 +10,7 @@ auth/cas/CAS/
 auth/fc/fcFPP.php
 enrol/lti/ims-blti/
 filter/algebra/AlgParser.pm
+filter/mathjaxloader/contrib/a11y/
 filter/tex/mimetex.*
 lib/editor/atto/yui/src/rangy/js/*.*
 lib/editor/tinymce/plugins/pdw/tinymce/
index 451a504..2d6c362 100644 (file)
@@ -1612,7 +1612,7 @@ class core_admin_renderer extends plugin_renderer_base {
                 $row = new html_table_row();
                 $row->attributes['class'] = 'type-' . $plugin->type . ' name-' . $plugin->type . '_' . $plugin->name;
 
-                if ($this->page->theme->resolve_image_location('icon', $plugin->type . '_' . $plugin->name)) {
+                if ($this->page->theme->resolve_image_location('icon', $plugin->type . '_' . $plugin->name, null)) {
                     $icon = $this->output->pix_icon('icon', '', $plugin->type . '_' . $plugin->name, array('class' => 'icon pluginicon'));
                 } else {
                     $icon = $this->output->spacer();
index 775f006..74de88a 100644 (file)
@@ -1012,7 +1012,7 @@ class manager {
         $messageparams = new \stdClass();
         $messageparams->html    = $message->html;
         $messageparams->plain   = $message->plain;
-        $messagepreferencesurl = new \moodle_url("/message/edit.php", array('id' => $USER->id));
+        $messagepreferencesurl = new \moodle_url("/message/notificationpreferences.php", array('id' => $USER->id));
         $messageparams->messagepreferencesurl = $messagepreferencesurl->out();
         $htmlmessage = get_string('messageprocessingsuccesshtml', 'tool_messageinbound', $messageparams);
         $plainmessage = get_string('messageprocessingsuccess', 'tool_messageinbound', $messageparams);
index 68363af..1545996 100644 (file)
@@ -153,6 +153,14 @@ class api {
             $settings['compactlogourl'] = $compactlogourl->out(false);
         }
 
+        // Identity providers.
+        $authsequence = get_enabled_auth_plugins(true);
+        $identityproviders = \auth_plugin_base::get_identity_providers($authsequence);
+        $identityprovidersdata = \auth_plugin_base::prepare_identity_providers_for_output($identityproviders, $OUTPUT);
+        if (!empty($identityprovidersdata)) {
+            $settings['identityproviders'] = $identityprovidersdata;
+        }
+
         return $settings;
     }
 
index d56966e..a9fdd1f 100644 (file)
@@ -150,6 +150,16 @@ class external extends external_api {
                 'launchurl' => new external_value(PARAM_URL, 'SSO login launch URL. Empty if it won\'t be used.', VALUE_OPTIONAL),
                 'mobilecssurl' => new external_value(PARAM_URL, 'Mobile custom CSS theme', VALUE_OPTIONAL),
                 'tool_mobile_disabledfeatures' => new external_value(PARAM_RAW, 'Disabled features in the app', VALUE_OPTIONAL),
+                'identityproviders' => new external_multiple_structure(
+                    new external_single_structure(
+                        array(
+                            'name' => new external_value(PARAM_TEXT, 'The identity provider name.'),
+                            'iconurl' => new external_value(PARAM_URL, 'The icon URL for the provider.'),
+                            'url' => new external_value(PARAM_URL, 'The URL of the provider.'),
+                        )
+                    ),
+                    'Identity providers', VALUE_OPTIONAL
+                ),
                 'warnings' => new external_warnings(),
             )
         );
index a5a7154..1e74e37 100644 (file)
@@ -32,12 +32,23 @@ $serviceshortname  = required_param('service',  PARAM_ALPHANUMEXT);
 $passport          = required_param('passport',  PARAM_RAW);    // Passport send from the app to validate the response URL.
 $urlscheme         = optional_param('urlscheme', 'moodlemobile', PARAM_NOTAGS); // The URL scheme the app supports.
 $confirmed         = optional_param('confirmed', false, PARAM_BOOL);  // If we are being redirected after user confirmation.
+$oauthsso          = optional_param('oauthsso', 0, PARAM_INT); // Id of the OpenID issuer (for OAuth direct SSO).
 
 // Check web services enabled.
 if (!$CFG->enablewebservices) {
     throw new moodle_exception('enablewsdescription', 'webservice');
 }
 
+// We have been requested to start a SSO process via OpenID.
+if (!empty($oauthsso) && is_enabled_auth('oauth2')) {
+    $wantsurl = new moodle_url('/admin/tool/mobile/launch.php',
+        array('service' => $serviceshortname, 'passport' => $passport, 'urlscheme' => $urlscheme, 'confirmed' => $confirmed));
+    $oauthurl = new moodle_url('/auth/oauth2/login.php',
+        array('id' => $oauthsso, 'sesskey' => sesskey(), 'wantsurl' => $wantsurl));
+    header('Location: ' . $oauthurl->out(false));
+    die;
+}
+
 // Check if the plugin is properly configured.
 $typeoflogin = get_config('tool_mobile', 'typeoflogin');
 if (empty($SESSION->justloggedin) and
index ccfc819..9a93520 100644 (file)
@@ -4,4 +4,5 @@ Information provided here is intended especially for developers.
 === 3.3 ===
 
  * External function tool_mobile::get_public_config now returns the mobilecssurl field (Mobile custom CSS theme).
+ * External function tool_mobile::get_public_config now returns the identityproviders field (list of external identity providers).
 
index a86924e..40214ba 100644 (file)
Binary files a/admin/tool/usertours/amd/build/popper.min.js and b/admin/tool/usertours/amd/build/popper.min.js differ
index eaeb288..84a70c2 100644 (file)
Binary files a/admin/tool/usertours/amd/build/tour.min.js and b/admin/tool/usertours/amd/build/tour.min.js differ
index c0fb1d7..a1d9d8c 100644 (file)
-
-/*
-* @fileOverview Kickass library to create and place poppers near their reference elements.
-* @version 1.0.0-alpha.3
-* @license
-* Copyright (c) 2016 Federico Zivolo and contributors
-*
-* Permission is hereby granted, free of charge, to any person obtaining a copy
-* of this software and associated documentation files (the "Software"), to deal
-* in the Software without restriction, including without limitation the rights
-* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-* copies of the Software, and to permit persons to whom the Software is
-* furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice shall be included in all
-* copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-* SOFTWARE.
-*/
-                    
+/**!
+ * @fileOverview Kickass library to create and place poppers near their reference elements.
+ * @version 1.0.8
+ * @license
+ * Copyright (c) 2016 Federico Zivolo and contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */    
 (function (global, factory) {
-  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
-  typeof define === 'function' && define.amd ? define(factory) :
-  (global.Popper = factory());
-}(this, function () { 'use strict';
-
-  /**
-   * The Object.assign() method is used to copy the values of all enumerable own properties from one or more source
-   * objects to a target object. It will return the target object.
-   * This polyfill doesn't support symbol properties, since ES5 doesn't have symbols anyway
-   * Source: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
-   * @function
-   * @ignore
-   */
-  if (!Object.assign) {
-      Object.defineProperty(Object, 'assign', {
-          enumerable: false,
-          configurable: true,
-          writable: true,
-          value: function value(target) {
-              if (target === undefined || target === null) {
-                  throw new TypeError('Cannot convert first argument to object');
-              }
-
-              var to = Object(target);
-              for (var i = 1; i < arguments.length; i++) {
-                  var nextSource = arguments[i];
-                  if (nextSource === undefined || nextSource === null) {
-                      continue;
-                  }
-                  nextSource = Object(nextSource);
-
-                  var keysArray = Object.keys(nextSource);
-                  for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
-                      var nextKey = keysArray[nextIndex];
-                      var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
-                      if (desc !== undefined && desc.enumerable) {
-                          to[nextKey] = nextSource[nextKey];
-                      }
-                  }
-              }
-              return to;
-          }
-      });
-  }
+       typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+       typeof define === 'function' && define.amd ? define(factory) :
+       (global.Popper = factory());
+}(this, (function () { 'use strict';
+
+/**
+ * Returns the offset parent of the given element
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element
+ * @returns {Element} offset parent
+ */
+function getOffsetParent(element) {
+    // NOTE: 1 DOM access here
+    var offsetParent = element.offsetParent;
+    var nodeName = offsetParent && offsetParent.nodeName;
 
-  /**
-   * Polyfill for requestAnimationFrame
-   * @function
-   * @ignore
-   */
-  if (!window.requestAnimationFrame) {
-      var lastTime = 0;
-      var vendors = ['ms', 'moz', 'webkit', 'o'];
-      for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
-          window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
-          window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
-      }
+    if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {
+        return window.document.documentElement;
+    }
 
-      if (!window.requestAnimationFrame) {
-          window.requestAnimationFrame = function (callback) {
-              var currTime = new Date().getTime();
-              var timeToCall = Math.max(0, 16 - (currTime - lastTime));
-              var id = window.setTimeout(function () {
-                  callback(currTime + timeToCall);
-              }, timeToCall);
-              lastTime = currTime + timeToCall;
-              return id;
-          };
-      }
+    return offsetParent;
+}
+
+/**
+ * Get CSS computed property of the given element
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Eement} element
+ * @argument {String} property
+ */
+function getStyleComputedProperty(element, property) {
+    if (element.nodeType !== 1) {
+        return [];
+    }
+    // NOTE: 1 DOM access here
+    var css = window.getComputedStyle(element, null);
+    return property ? css[property] : css;
+}
+
+/**
+ * Returns the parentNode or the host of the element
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element
+ * @returns {Element} parent
+ */
+function getParentNode(element) {
+    if (element.nodeName === 'HTML') {
+        return element;
+    }
+    return element.parentNode || element.host;
+}
+
+/**
+ * Returns the scrolling parent of the given element
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element
+ * @returns {Element} scroll parent
+ */
+function getScrollParent(element) {
+    // Return body, `getScroll` will take care to get the correct `scrollTop` from it
+    if (!element || ['HTML', 'BODY', '#document'].indexOf(element.nodeName) !== -1) {
+        return window.document.body;
+    }
 
-      if (!window.cancelAnimationFrame) {
-          window.cancelAnimationFrame = function (id) {
-              clearTimeout(id);
-          };
-      }
-  }
+    // Firefox want us to check `-x` and `-y` variations as well
 
-  /**
-   * Return the index of the matching object
-   * @method
-   * @memberof Popper.Utils
-   * @argument {Array} arr
-   * @argument prop
-   * @argument value
-   * @returns index or -1
-   */
-  function findIndex(arr, prop, value) {
-    // use filter instead of find because find has less cross-browser support
-    var match = arr.filter(function (obj) {
-      return obj[prop] === value;
-    })[0];
-    return arr.indexOf(match);
-  }
+    var _getStyleComputedProp = getStyleComputedProperty(element),
+        overflow = _getStyleComputedProp.overflow,
+        overflowX = _getStyleComputedProp.overflowX,
+        overflowY = _getStyleComputedProp.overflowY;
 
-  /**
-   * Returns the offset parent of the given element
-   * @method
-   * @memberof Popper.Utils
-   * @argument {Element} element
-   * @returns {Element} offset parent
-   */
-  function getOffsetParent(element) {
-    // NOTE: 1 DOM access here
-    var offsetParent = element.offsetParent;
-    return !offsetParent || offsetParent.nodeName === 'BODY' ? window.document.documentElement : offsetParent;
-  }
+    if (/(auto|scroll)/.test(overflow + overflowY + overflowX)) {
+        return element;
+    }
 
-  /**
-   * Get CSS computed property of the given element
-   * @method
-   * @memberof Popper.Utils
-   * @argument {Eement} element
-   * @argument {String} property
-   */
-  function getStyleComputedProperty(element, property) {
-      if (element.nodeType !== 1) {
-          return [];
-      }
-      // NOTE: 1 DOM access here
-      var css = window.getComputedStyle(element, null);
-      return css[property];
-  }
+    return getScrollParent(getParentNode(element));
+}
+
+/**
+ * Check if the given element is fixed or is inside a fixed parent
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element
+ * @argument {Element} customContainer
+ * @returns {Boolean} answer to "isFixed?"
+ */
+function isFixed(element) {
+    var nodeName = element.nodeName;
+    if (nodeName === 'BODY' || nodeName === 'HTML') {
+        return false;
+    }
+    if (getStyleComputedProperty(element, 'position') === 'fixed') {
+        return true;
+    }
+    return isFixed(getParentNode(element));
+}
+
+/**
+ * Helper used to get the position which will be applied to the popper
+ * @method
+ * @memberof Popper.Utils
+ * @param {HTMLElement} element - popper element
+ * @returns {String} position
+ */
+function getPosition(element) {
+  var container = getOffsetParent(element);
+
+  // Decide if the popper will be fixed
+  // If the reference element is inside a fixed context, the popper will be fixed as well to allow them to scroll together
+  var isParentFixed = isFixed(container);
+  return isParentFixed ? 'fixed' : 'absolute';
+}
 
-  /**
-   * Returns the parentNode or the host of the element
-   * @method
-   * @memberof Popper.Utils
-   * @argument {Element} element
-   * @returns {Element} parent
-   */
-  function getParentNode(element) {
-    return element.parentNode || element.host;
-  }
+/*
+ * Helper to detect borders of a given element
+ * @method
+ * @memberof Popper.Utils
+ * @param {CSSStyleDeclaration} styles - result of `getStyleComputedProperty` on the given element
+ * @param {String} axis - `x` or `y`
+ * @return {Number} borders - the borders size of the given axis
+ */
+
+function getBordersSize(styles, axis) {
+  var sideA = axis === 'x' ? 'Left' : 'Top';
+  var sideB = sideA === 'Left' ? 'Right' : 'Bottom';
+
+  return Number(styles['border' + sideA + 'Width'].split('px')[0]) + Number(styles['border' + sideB + 'Width'].split('px')[0]);
+}
+
+/**
+ * Get bounding client rect of given element
+ * @method
+ * @memberof Popper.Utils
+ * @param {HTMLElement} element
+ * @return {Object} client rect
+ */
+function getBoundingClientRect(element) {
+    var isIE10 = navigator.appVersion.indexOf('MSIE 10') !== -1;
+    var rect = void 0;
+
+    // IE10 10 FIX: Please, don't ask, the element isn't
+    // considered in DOM in some circumstances...
+    // This isn't reproducible in IE10 compatibility mode of IE11
+    if (isIE10) {
+        try {
+            rect = element.getBoundingClientRect();
+        } catch (err) {
+            rect = {};
+        }
+    } else {
+        rect = element.getBoundingClientRect();
+    }
 
-  /**
-   * Returns the scrolling parent of the given element
-   * @method
-   * @memberof Popper.Utils
-   * @argument {Element} element
-   * @returns {Element} offset parent
-   */
-  function getScrollParent(element) {
-      if (element === window.document) {
-          // Firefox puts the scrollTOp value on `documentElement` instead of `body`, we then check which of them is
-          // greater than 0 and return the proper element
-          if (window.document.body.scrollTop) {
-              return window.document.body;
-          } else {
-              return window.document.documentElement;
-          }
-      }
+    var result = {
+        left: rect.left,
+        top: rect.top,
+        right: rect.right,
+        bottom: rect.bottom,
+        width: rect.right - rect.left,
+        height: rect.bottom - rect.top
+    };
 
-      // Firefox want us to check `-x` and `-y` variations as well
-      if (['scroll', 'auto'].indexOf(getStyleComputedProperty(element, 'overflow')) !== -1 || ['scroll', 'auto'].indexOf(getStyleComputedProperty(element, 'overflow-x')) !== -1 || ['scroll', 'auto'].indexOf(getStyleComputedProperty(element, 'overflow-y')) !== -1) {
-          // If the detected scrollParent is body, we perform an additional check on its parentNode
-          // in this way we'll get body if the browser is Chrome-ish, or documentElement otherwise
-          // fixes issue #65
-          return element === window.document.body ? getScrollParent(getParentNode(element)) : element;
-      }
-      return getParentNode(element) ? getScrollParent(getParentNode(element)) : element;
-  }
+    // IE10 FIX: `getBoundingClientRect`, when executed on `documentElement`
+    // will not take in account the `scrollTop` and `scrollLeft`
+    if (element.nodeName === 'HTML' && isIE10) {
+        var _window$document$docu = window.document.documentElement,
+            scrollTop = _window$document$docu.scrollTop,
+            scrollLeft = _window$document$docu.scrollLeft;
+
+        result.top -= scrollTop;
+        result.bottom -= scrollTop;
+        result.left -= scrollLeft;
+        result.right -= scrollLeft;
+    }
 
-  /**
-   * Get the position of the given element, relative to its offset parent
-   * @method
-   * @memberof Popper.Utils
-   * @param {Element} element
-   * @return {Object} position - Coordinates of the element and its `scrollTop`
-   */
-  function getOffsetRect(element) {
-      var elementRect = {
-          width: element.offsetWidth,
-          height: element.offsetHeight,
-          left: element.offsetLeft,
-          top: element.offsetTop
-      };
-
-      elementRect.right = elementRect.left + elementRect.width;
-      elementRect.bottom = elementRect.top + elementRect.height;
-
-      // position
-      return elementRect;
-  }
+    // subtract scrollbar size from sizes
+    var horizScrollbar = rect.width - (element.clientWidth || rect.right - rect.left);
+    var vertScrollbar = rect.height - (element.clientHeight || rect.bottom - rect.top);
 
-  /**
-   * Computed the boundaries limits and return them
-   * @method
-   * @memberof Popper.Utils
-   * @param {Object} data - Object containing the property "offsets" generated by `_getOffsets`
-   * @param {Number} padding - Boundaries padding
-   * @param {Element} boundariesElement - Element used to define the boundaries
-   * @returns {Object} Coordinates of the boundaries
-   */
-  function getBoundaries(popper, data, padding, boundariesElement) {
-      // NOTE: 1 DOM access here
-      var boundaries = {};
-      if (boundariesElement === 'window') {
-          var body = window.document.body;
-          var html = window.document.documentElement;
-          var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
-          var width = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth);
-
-          boundaries = {
-              top: 0,
-              right: width,
-              bottom: height,
-              left: 0
-          };
-      } else if (boundariesElement === 'viewport') {
-          var offsetParent = getOffsetParent(popper);
-          var scrollParent = getScrollParent(popper);
-          var offsetParentRect = getOffsetRect(offsetParent);
-
-          // if the popper is fixed we don't have to substract scrolling from the boundaries
-          var scrollTop = data.offsets.popper.position === 'fixed' ? 0 : scrollParent.scrollTop;
-          var scrollLeft = data.offsets.popper.position === 'fixed' ? 0 : scrollParent.scrollLeft;
-
-          boundaries = {
-              top: 0 - (offsetParentRect.top - scrollTop),
-              right: window.document.documentElement.clientWidth - (offsetParentRect.left - scrollLeft),
-              bottom: window.document.documentElement.clientHeight - (offsetParentRect.top - scrollTop),
-              left: 0 - (offsetParentRect.left - scrollLeft)
-          };
-      } else {
-          if (getOffsetParent(popper) === boundariesElement) {
-              boundaries = {
-                  top: 0,
-                  left: 0,
-                  right: boundariesElement.clientWidth,
-                  bottom: boundariesElement.clientHeight
-              };
-          } else {
-              boundaries = getOffsetRect(boundariesElement);
-          }
-      }
-      boundaries.left += padding;
-      boundaries.right -= padding;
-      boundaries.top = boundaries.top + padding;
-      boundaries.bottom = boundaries.bottom - padding;
-      return boundaries;
-  }
+    // if an hypothetical scrollbar is detected, we must be sure it's not a `border`
+    // we make this check conditional for performance reasons
+    if (horizScrollbar || vertScrollbar) {
+        var styles = getStyleComputedProperty(element);
+        horizScrollbar -= getBordersSize(styles, 'x');
+        vertScrollbar -= getBordersSize(styles, 'y');
+    }
 
-  /**
-   * Get bounding client rect of given element
-   * @method
-   * @memberof Popper.Utils
-   * @param {HTMLElement} element
-   * @return {Object} client rect
-   */
-  function getBoundingClientRect(element) {
-      var rect = element.getBoundingClientRect();
-      return {
-          left: rect.left,
-          top: rect.top,
-          right: rect.right,
-          bottom: rect.bottom,
-          width: rect.right - rect.left,
-          height: rect.bottom - rect.top
-      };
-  }
+    result.right -= horizScrollbar;
+    result.width -= horizScrollbar;
+    result.bottom -= vertScrollbar;
+    result.height -= vertScrollbar;
 
-  /**
-   * Given an element and one of its parents, return the offset
-   * @method
-   * @memberof Popper.Utils
-   * @param {HTMLElement} element
-   * @param {HTMLElement} parent
-   * @return {Object} rect
-   */
-  function getOffsetRectRelativeToCustomParent(element, parent, fixed, transformed) {
-      var elementRect = getBoundingClientRect(element);
-      var parentRect = getBoundingClientRect(parent);
-
-      if (fixed && !transformed) {
-          var scrollParent = getScrollParent(parent);
-          parentRect.top += scrollParent.scrollTop;
-          parentRect.bottom += scrollParent.scrollTop;
-          parentRect.left += scrollParent.scrollLeft;
-          parentRect.right += scrollParent.scrollLeft;
-      }
+    return result;
+}
 
-      var rect = {
-          top: elementRect.top - parentRect.top,
-          left: elementRect.left - parentRect.left,
-          bottom: elementRect.top - parentRect.top + elementRect.height,
-          right: elementRect.left - parentRect.left + elementRect.width,
-          width: elementRect.width,
-          height: elementRect.height
-      };
-      return rect;
-  }
+function getScroll(element) {
+    var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';
 
-  /**
-   * Get the outer sizes of the given element (offset size + margins)
-   * @method
-   * @memberof Popper.Utils
-   * @argument {Element} element
-   * @returns {Object} object containing width and height properties
-   */
-  function getOuterSizes(element) {
-      // NOTE: 1 DOM access here
-      var display = element.style.display;
-      var visibility = element.style.visibility;
-
-      element.style.display = 'block';
-      element.style.visibility = 'hidden';
-
-      // original method
-      var styles = window.getComputedStyle(element);
-      var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);
-      var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);
-      var result = {
-          width: element.offsetWidth + y,
-          height: element.offsetHeight + x
-      };
-
-      // reset element styles
-      element.style.display = display;
-      element.style.visibility = visibility;
-
-      return result;
-  }
+    var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';
+    var nodeName = element.nodeName;
 
-  /**
-   * Given the popper offsets, generate an output similar to getBoundingClientRect
-   * @method
-   * @memberof Popper.Utils
-   * @argument {Object} popperOffsets
-   * @returns {Object} ClientRect like output
-   */
-  function getPopperClientRect(popperOffsets) {
-      return Object.assign({}, popperOffsets, {
-          right: popperOffsets.left + popperOffsets.width,
-          bottom: popperOffsets.top + popperOffsets.height
-      });
-  }
+    if (nodeName === 'BODY' || nodeName === 'HTML') {
+        var html = window.document.documentElement;
+        var scrollingElement = window.document.scrollingElement || html;
+        return scrollingElement[upperSide];
+    }
 
-  /**
-   * Check if the given element is fixed or is inside a fixed parent
-   * @method
-   * @memberof Popper.Utils
-   * @argument {Element} element
-   * @argument {Element} customContainer
-   * @returns {Boolean} answer to "isFixed?"
-   */
-  function isFixed(element) {
-      if (element === window.document.body) {
-          return false;
-      }
-      if (getStyleComputedProperty(element, 'position') === 'fixed') {
-          return true;
-      }
-      return getParentNode(element) ? isFixed(getParentNode(element)) : element;
-  }
+    return element[upperSide];
+}
 
-  /**
-   * Helper used to get the position which will be applied to the popper
-   * @method
-   * @memberof Popper.Utils
-   * @param config {HTMLElement} popper element
-   * @returns {HTMLElement} reference element
-   */
-  function getPosition(popper, reference) {
-    var container = getOffsetParent(reference);
-
-    // Decide if the popper will be fixed
-    // If the reference element is inside a fixed context, the popper will be fixed as well to allow them to scroll together
-    var isParentFixed = isFixed(container);
-    return isParentFixed ? 'fixed' : 'absolute';
-  }
+/*
+ * Sum or subtract the element scroll values (left and top) from a given rect object
+ * @method
+ * @memberof Popper.Utils
+ * @param {Object} rect - Rect object you want to change
+ * @param {HTMLElement} element - The element from the function reads the scroll values
+ * @param {Boolean} subtract - set to true if you want to subtract the scroll values
+ * @return {Object} rect - The modifier rect object
+ */
+function includeScroll(rect, element) {
+  var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
+
+  var scrollTop = getScroll(element, 'top');
+  var scrollLeft = getScroll(element, 'left');
+  var modifier = subtract ? -1 : 1;
+  rect.top += scrollTop * modifier;
+  rect.bottom += scrollTop * modifier;
+  rect.left += scrollLeft * modifier;
+  rect.right += scrollLeft * modifier;
+  return rect;
+}
+
+/**
+ * Given an element and one of its parents, return the offset
+ * @method
+ * @memberof Popper.Utils
+ * @param {HTMLElement} element
+ * @param {HTMLElement} parent
+ * @return {Object} rect
+ */
+function getOffsetRectRelativeToCustomParent(element, parent) {
+    var fixed = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
+    var transformed = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
+
+    var scrollParent = getScrollParent(parent);
+    var elementRect = getBoundingClientRect(element);
+    var parentRect = getBoundingClientRect(parent);
+
+    var rect = {
+        top: elementRect.top - parentRect.top,
+        left: elementRect.left - parentRect.left,
+        bottom: elementRect.top - parentRect.top + elementRect.height,
+        right: elementRect.left - parentRect.left + elementRect.width,
+        width: elementRect.width,
+        height: elementRect.height
+    };
 
-  /**
-   * Get the prefixed supported property name
-   * @method
-   * @memberof Popper.Utils
-   * @argument {String} property (camelCase)
-   * @returns {String} prefixed property (camelCase)
-   */
-  function getSupportedPropertyName(property) {
-      var prefixes = ['', 'ms', 'webkit', 'moz', 'o'];
-
-      for (var i = 0; i < prefixes.length; i++) {
-          var toCheck = prefixes[i] ? prefixes[i] + property.charAt(0).toUpperCase() + property.slice(1) : property;
-          if (typeof window.document.body.style[toCheck] !== 'undefined') {
-              return toCheck;
-          }
-      }
-      return null;
-  }
+    if (fixed && !transformed) {
+        rect = includeScroll(rect, scrollParent, true);
+    }
+    // When a popper doesn't have any positioned or scrollable parents, `offsetParent.contains(scrollParent)`
+    // will return a "false positive". This is happening because `getOffsetParent` returns `html` node,
+    // and `scrollParent` is the `body` node. Hence the additional check.
+    else if (getOffsetParent(element).contains(scrollParent) && scrollParent.nodeName !== 'BODY') {
+            rect = includeScroll(rect, parent);
+        }
+
+    // subtract borderTopWidth and borderTopWidth from final result
+    var styles = getStyleComputedProperty(parent);
+    var borderTopWidth = Number(styles.borderTopWidth.split('px')[0]);
+    var borderLeftWidth = Number(styles.borderLeftWidth.split('px')[0]);
+
+    rect.top -= borderTopWidth;
+    rect.bottom -= borderTopWidth;
+    rect.left -= borderLeftWidth;
+    rect.right -= borderLeftWidth;
+
+    return rect;
+}
+
+function getWindowSizes() {
+    var body = window.document.body;
+    var html = window.document.documentElement;
+    return {
+        height: Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight),
+        width: Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth)
+    };
+}
+
+/**
+ * Get the position of the given element, relative to its offset parent
+ * @method
+ * @memberof Popper.Utils
+ * @param {Element} element
+ * @return {Object} position - Coordinates of the element and its `scrollTop`
+ */
+function getOffsetRect(element) {
+    var elementRect = void 0;
+    if (element.nodeName === 'HTML') {
+        var _getWindowSizes = getWindowSizes(),
+            width = _getWindowSizes.width,
+            height = _getWindowSizes.height;
+
+        elementRect = {
+            width: width,
+            height: height,
+            left: 0,
+            top: 0
+        };
+    } else {
+        elementRect = {
+            width: element.offsetWidth,
+            height: element.offsetHeight,
+            left: element.offsetLeft,
+            top: element.offsetTop
+        };
+    }
 
-  /**
-   * Check if the given variable is a function
-   * @method
-   * @memberof Popper.Utils
-   * @argument {Element} element - Element to check
-   * @returns {Boolean} answer to: is a function?
-   */
-  function isFunction(functionToCheck) {
-    var getType = {};
-    return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
-  }
+    elementRect.right = elementRect.left + elementRect.width;
+    elementRect.bottom = elementRect.top + elementRect.height;
+
+    // position
+    return elementRect;
+}
+
+function getOffsetRectRelativeToViewport(element) {
+    // Offset relative to offsetParent
+    var relativeOffset = getOffsetRect(element);
+
+    if (element.nodeName !== 'HTML') {
+        var offsetParent = getOffsetParent(element);
+        var parentOffset = getOffsetRectRelativeToViewport(offsetParent);
+        var offset = {
+            width: relativeOffset.offsetWidth,
+            height: relativeOffset.offsetHeight,
+            left: relativeOffset.left + parentOffset.left,
+            top: relativeOffset.top + parentOffset.top,
+            right: relativeOffset.right - parentOffset.right,
+            bottom: relativeOffset.bottom - parentOffset.bottom
+        };
+        return offset;
+    }
 
-  /**
-   * Helper used to know if the given modifier depends from another one.
-   * @method
-   * @memberof Popper.Utils
-   * @returns {Boolean}
-   */
-  function isModifierRequired(modifiers, requesting, requested) {
-      return !!modifiers.filter(function (modifier) {
-          if (modifier.name === requested) {
-              return true;
-          } else if (modifier.name === requesting) {
-              return false;
-          }
-          return false;
-      }).length;
-  }
+    return relativeOffset;
+}
 
-  /**
-   * Tells if a given input is a number
-   * @method
-   * @memberof Popper.Utils
-   * @param {*} input to check
-   * @return {Boolean}
-   */
-  function isNumeric(n) {
-    return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);
-  }
+function getTotalScroll(element) {
+    var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';
 
-  /**
-   * Check if the given element has transforms applied to itself or a parent
-   * @method
-   * @memberof Popper.Utils
-   * @param  {Element} element
-   * @return {Boolean} answer to "isTransformed?"
-   */
-  function isTransformed(element) {
-      if (element === window.document.body) {
-          return false;
-      }
-      if (getStyleComputedProperty(element, 'transform') !== 'none') {
-          return true;
-      }
-      return getParentNode(element) ? isTransformed(getParentNode(element)) : element;
-  }
+    var scrollParent = getScrollParent(element);
+    var scroll = getScroll(scrollParent, side);
 
-  /**
-   * Loop trough the list of modifiers and run them in order, each of them will then edit the data object
-   * @method
-   * @memberof Popper.Utils
-   * @param {Object} data
-   * @param {Array} modifiers
-   * @param {Function} ends
-   */
-  function runModifiers(modifiers, options, data, ends) {
-      var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));
-
-      modifiersToRun.forEach(function (modifier) {
-          if (modifier.enabled && isFunction(modifier.function)) {
-              data = modifier.function(data, modifier);
-          }
-      });
-
-      return data;
-  }
+    if (['BODY', 'HTML'].indexOf(scrollParent.nodeName) === -1) {
+        return scroll + getTotalScroll(getParentNode(scrollParent), side);
+    }
+    return scroll;
+}
+
+/**
+ * Computed the boundaries limits and return them
+ * @method
+ * @memberof Popper.Utils
+ * @param {Object} data - Object containing the property "offsets" generated by `_getOffsets`
+ * @param {Number} padding - Boundaries padding
+ * @param {Element} boundariesElement - Element used to define the boundaries
+ * @returns {Object} Coordinates of the boundaries
+ */
+function getBoundaries(popper, padding, boundariesElement) {
+    // NOTE: 1 DOM access here
+    var boundaries = { top: 0, left: 0 };
+    var offsetParent = getOffsetParent(popper);
+
+    // Handle viewport case
+    if (boundariesElement === 'viewport') {
+        var _getOffsetRectRelativ = getOffsetRectRelativeToViewport(offsetParent),
+            left = _getOffsetRectRelativ.left,
+            top = _getOffsetRectRelativ.top;
+
+        var _window$document$docu = window.document.documentElement,
+            width = _window$document$docu.clientWidth,
+            height = _window$document$docu.clientHeight;
+
+
+        if (getPosition(popper) === 'fixed') {
+            boundaries.right = width;
+            boundaries.bottom = height;
+        } else {
+            var scrollLeft = getTotalScroll(popper, 'left');
+            var scrollTop = getTotalScroll(popper, 'top');
+
+            boundaries = {
+                top: 0 - top,
+                right: width - left + scrollLeft,
+                bottom: height - top + scrollTop,
+                left: 0 - left
+            };
+        }
+    }
+    // Handle other cases based on DOM element used as boundaries
+    else {
+            var boundariesNode = void 0;
+            if (boundariesElement === 'scrollParent') {
+                boundariesNode = getScrollParent(getParentNode(popper));
+            } else if (boundariesElement === 'window') {
+                boundariesNode = window.document.body;
+            } else {
+                boundariesNode = boundariesElement;
+            }
+
+            // In case of BODY, we need a different computation
+            if (boundariesNode.nodeName === 'BODY') {
+                var _getWindowSizes = getWindowSizes(),
+                    _height = _getWindowSizes.height,
+                    _width = _getWindowSizes.width;
+
+                boundaries.right = _width;
+                boundaries.bottom = _height;
+            }
+            // for all the other DOM elements, this one is good
+            else {
+                    boundaries = getOffsetRectRelativeToCustomParent(boundariesNode, offsetParent, isFixed(popper));
+                }
+        }
+
+    // Add paddings
+    boundaries.left += padding;
+    boundaries.top += padding;
+    boundaries.right -= padding;
+    boundaries.bottom -= padding;
+
+    return boundaries;
+}
+
+/**
+ * Utility used to transform the `auto` placement to the placement with more
+ * available space.
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function computeAutoPlacement(placement, refRect, popper) {
+    if (placement.indexOf('auto') === -1) {
+        return placement;
+    }
 
-  /**
-   * Set the style to the given popper
-   * @method
-   * @memberof Popper.Utils
-   * @argument {Element} element - Element to apply the style to
-   * @argument {Object} styles - Object with a list of properties and values which will be applied to the element
-   */
-  function setStyle(element, styles) {
-      Object.keys(styles).forEach(function (prop) {
-          var unit = '';
-          // add unit if the value is numeric and is one of the following
-          if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {
-              unit = 'px';
-          }
-          element.style[prop] = styles[prop] + unit;
-      });
-  }
+    var boundaries = getBoundaries(popper, 0, 'scrollParent');
 
-  /** @namespace Popper.Utils */
-  var Utils = {
-      findIndex: findIndex,
-      getBoundaries: getBoundaries,
-      getBoundingClientRect: getBoundingClientRect,
-      getOffsetParent: getOffsetParent,
-      getOffsetRectRelativeToCustomParent: getOffsetRectRelativeToCustomParent,
-      getOuterSizes: getOuterSizes,
-      getPopperClientRect: getPopperClientRect,
-      getPosition: getPosition,
-      getScrollParent: getScrollParent,
-      getStyleComputedProperty: getStyleComputedProperty,
-      getSupportedPropertyName: getSupportedPropertyName,
-      isFixed: isFixed,
-      isFunction: isFunction,
-      isModifierRequired: isModifierRequired,
-      isNumeric: isNumeric,
-      isTransformed: isTransformed,
-      runModifiers: runModifiers,
-      setStyle: setStyle
-  };
+    var sides = {
+        top: refRect.top - boundaries.top,
+        right: boundaries.right - refRect.right,
+        bottom: boundaries.bottom - refRect.bottom,
+        left: refRect.left - boundaries.left
+    };
 
-  /**
-   * Get offsets to the popper
-   * @method
-   * @memberof Popper.Utils
-   * @param {Element} popper - the popper element
-   * @param {Element} reference - the reference element (the popper will be relative to this)
-   * @returns {Object} An object containing the offsets which will be applied to the popper
-   */
-  function getOffsets(state, popper, reference, placement) {
-      placement = placement.split('-')[0];
-
-      var popperOffsets = {};
-      popperOffsets.position = state.position;
-
-      var isParentFixed = popperOffsets.position === 'fixed';
-      var isParentTransformed = state.isParentTransformed;
-
-      //
-      // Get reference element position
-      //
-      var offsetParent = getOffsetParent(isParentFixed && isParentTransformed ? reference : popper);
-      var referenceOffsets = getOffsetRectRelativeToCustomParent(reference, offsetParent, isParentFixed, isParentTransformed);
-
-      //
-      // Get popper sizes
-      //
-      var popperRect = getOuterSizes(popper);
-
-      //
-      // Compute offsets of popper
-      //
-
-      // depending by the popper placement we have to compute its offsets slightly differently
-      if (['right', 'left'].indexOf(placement) !== -1) {
-          popperOffsets.top = referenceOffsets.top + referenceOffsets.height / 2 - popperRect.height / 2;
-          if (placement === 'left') {
-              popperOffsets.left = referenceOffsets.left - popperRect.width;
-          } else {
-              popperOffsets.left = referenceOffsets.right;
-          }
-      } else {
-          popperOffsets.left = referenceOffsets.left + referenceOffsets.width / 2 - popperRect.width / 2;
-          if (placement === 'top') {
-              popperOffsets.top = referenceOffsets.top - popperRect.height;
-          } else {
-              popperOffsets.top = referenceOffsets.bottom;
-          }
-      }
+    var computedPlacement = Object.keys(sides).sort(function (a, b) {
+        return sides[b] - sides[a];
+    })[0];
+    var variation = placement.split('-')[1];
+
+    return computedPlacement + (variation ? '-' + variation : '');
+}
+
+var nativeHints = ['native code', '[object MutationObserverConstructor]' // for mobile safari iOS 9.0
+];
+
+/**
+ * Determine if a function is implemented natively (as opposed to a polyfill).
+ * @argument {Function | undefined} fn the function to check
+ * @returns {boolean}
+ */
+var isNative = (function (fn) {
+  return nativeHints.some(function (hint) {
+    return (fn || '').toString().indexOf(hint) > -1;
+  });
+});
+
+var isBrowser = typeof window !== 'undefined';
+var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];
+var timeoutDuration = 0;
+for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {
+    if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {
+        timeoutDuration = 1;
+        break;
+    }
+}
+
+function microtaskDebounce(fn) {
+    var scheduled = false;
+    var i = 0;
+    var elem = document.createElement('span');
+
+    // MutationObserver provides a mechanism for scheduling microtasks, which
+    // are scheduled *before* the next task. This gives us a way to debounce
+    // a function but ensure it's called *before* the next paint.
+    var observer = new MutationObserver(function () {
+        fn();
+        scheduled = false;
+    });
 
-      // Add width and height to our offsets object
-      popperOffsets.width = popperRect.width;
-      popperOffsets.height = popperRect.height;
+    observer.observe(elem, { attributes: true });
 
-      return {
-          popper: popperOffsets,
-          reference: referenceOffsets
-      };
-  }
+    return function () {
+        if (!scheduled) {
+            scheduled = true;
+            elem.setAttribute('x-index', i);
+            i = i + 1; // don't use compund (+=) because it doesn't get optimized in V8
+        }
+    };
+}
+
+function taskDebounce(fn) {
+    var scheduled = false;
+    return function () {
+        if (!scheduled) {
+            scheduled = true;
+            setTimeout(function () {
+                scheduled = false;
+                fn();
+            }, timeoutDuration);
+        }
+    };
+}
 
-  /**
-   * Setup needed event listeners used to update the popper position
-   * @method
-   * @memberof Popper.Utils
-   * @private
-   */
-  function setupEventListeners(reference, options, state, updateBound) {
-      // NOTE: 1 DOM access here
-      state.updateBound = updateBound;
-      window.addEventListener('resize', state.updateBound, { passive: true });
-      // if the boundariesElement is window we don't need to listen for the scroll event
-      if (options.boundariesElement !== 'window') {
-          var target = getScrollParent(reference);
-          // here it could be both `body` or `documentElement` thanks to Firefox, we then check both
-          if (target === window.document.body || target === window.document.documentElement) {
-              target = window;
-          }
-          target.addEventListener('scroll', state.updateBound, { passive: true });
-      }
-  }
+// It's common for MutationObserver polyfills to be seen in the wild, however
+// these rely on Mutation Events which only occur when an element is connected
+// to the DOM. The algorithm used in this module does not use a connected element,
+// and so we must ensure that a *native* MutationObserver is available.
+var supportsNativeMutationObserver = isBrowser && isNative(window.MutationObserver);
 
-  /**
-   * Remove event listeners used to update the popper position
-   * @method
-   * @memberof Popper.Utils
-   * @private
-   */
-  function removeEventListeners(reference, state, options) {
-      // NOTE: 1 DOM access here
-      window.removeEventListener('resize', state.updateBound);
-      if (options.boundariesElement !== 'window') {
-          var target = getScrollParent(reference);
-          // here it could be both `body` or `documentElement` thanks to Firefox, we then check both
-          if (target === window.document.body || target === window.document.documentElement) {
-              target = window;
-          }
-          target.removeEventListener('scroll', state.updateBound);
-      }
-      state.updateBound = null;
-      return state;
-  }
+/**
+* Create a debounced version of a method, that's asynchronously deferred
+* but called in the minimum time possible.
+*
+* @method
+* @memberof Popper.Utils
+* @argument {Function} fn
+* @returns {Function}
+*/
+var debounce = supportsNativeMutationObserver ? microtaskDebounce : taskDebounce;
+
+/**
+ * Mimics the `find` method of Array
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Array} arr
+ * @argument prop
+ * @argument value
+ * @returns index or -1
+ */
+function find(arr, check) {
+    // use native find if supported
+    if (Array.prototype.find) {
+        return arr.find(check);
+    }
 
-  /**
-   * Sorts the modifiers based on their `order` property
-   * @method
-   * @memberof Popper.Utils
-   */
-  function sortModifiers(a, b) {
-      if (a.order < b.order) {
-          return -1;
-      } else if (a.order > b.order) {
-          return 1;
-      }
-      return 0;
-  }
+    // use `filter` to obtain the same behavior of `find`
+    return arr.filter(check)[0];
+}
+
+/**
+ * Return the index of the matching object
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Array} arr
+ * @argument prop
+ * @argument value
+ * @returns index or -1
+ */
+function findIndex(arr, prop, value) {
+    // use native findIndex if supported
+    if (Array.prototype.findIndex) {
+        return arr.findIndex(function (cur) {
+            return cur[prop] === value;
+        });
+    }
 
-  /**
-   * Apply the computed styles to the popper element
-   * @method
-   * @memberof Modifiers
-   * @argument {Object} data - The data object generated by `update` method
-   * @argument {Object} options - Modifiers configuration and options
-   * @returns {Object} The same data object
-   */
-  function applyStyle(data) {
-      // apply the final offsets to the popper
-      // NOTE: 1 DOM access here
-      var styles = {
-          position: data.offsets.popper.position
-      };
-
-      // round top and left to avoid blurry text
-      var left = Math.round(data.offsets.popper.left);
-      var top = Math.round(data.offsets.popper.top);
-
-      // if gpuAcceleration is set to true and transform is supported, we use `translate3d` to apply the position to the popper
-      // we automatically use the supported prefixed version if needed
-      var prefixedProperty = getSupportedPropertyName('transform');
-      if (data.instance.options.gpuAcceleration && prefixedProperty) {
-          styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
-          styles.top = 0;
-          styles.left = 0;
-      }
-      // othwerise, we use the standard `left` and `top` properties
-      else {
-              styles.left = left;
-              styles.top = top;
-          }
-
-      // any property present in `data.styles` will be applied to the popper,
-      // in this way we can make the 3rd party modifiers add custom styles to it
-      // Be aware, modifiers could override the properties defined in the previous
-      // lines of this modifier!
-      Object.assign(styles, data.styles);
-
-      setStyle(data.instance.popper, styles);
-
-      // set an attribute which will be useful to style the tooltip (use it to properly position its arrow)
-      // NOTE: 1 DOM access here
-      data.instance.popper.setAttribute('x-placement', data.placement);
-
-      // if the arrow style has been computed, apply the arrow style
-      if (data.offsets.arrow) {
-          setStyle(data.arrowElement, data.offsets.arrow);
-      }
+    // use `find` + `indexOf` if `findIndex` isn't supported
+    var match = find(arr, function (obj) {
+        return obj[prop] === value;
+    });
+    return arr.indexOf(match);
+}
 
-      return data;
+var classCallCheck = function (instance, Constructor) {
+  if (!(instance instanceof Constructor)) {
+    throw new TypeError("Cannot call a class as a function");
   }
-
-  /**
-   * Set the x-placement attribute before everything else because it could be used to add margins to the popper
-   * margins needs to be calculated to get the correct popper offsets
-   * @method
-   * @memberof Popper.modifiers
-   * @param {HTMLElement} reference - The reference element used to position the popper
-   * @param {HTMLElement} popper - The HTML element used as popper.
-   * @param {Object} options - Popper.js options
-   */
-  function applyStyleOnLoad(reference, popper, options) {
-      popper.setAttribute('x-placement', options.placement);
+};
+
+var createClass = function () {
+  function defineProperties(target, props) {
+    for (var i = 0; i < props.length; i++) {
+      var descriptor = props[i];
+      descriptor.enumerable = descriptor.enumerable || false;
+      descriptor.configurable = true;
+      if ("value" in descriptor) descriptor.writable = true;
+      Object.defineProperty(target, descriptor.key, descriptor);
+    }
   }
 
-  /**
-   * Modifier used to move the arrows on the edge of the popper to make sure them are always between the popper and the reference element
-   * It will use the CSS outer size of the arrow element to know how many pixels of conjuction are needed
-   * @method
-   * @memberof Modifiers
-   * @argument {Object} data - The data object generated by update method
-   * @argument {Object} options - Modifiers configuration and options
-   * @returns {Object} The data object, properly modified
-   */
-  function arrow(data, options) {
-      var arrow = options.element;
-
-      // if the arrowElement is a string, suppose it's a CSS selector
-      if (typeof arrow === 'string') {
-          arrow = data.instance.popper.querySelector(arrow);
-      }
+  return function (Constructor, protoProps, staticProps) {
+    if (protoProps) defineProperties(Constructor.prototype, protoProps);
+    if (staticProps) defineProperties(Constructor, staticProps);
+    return Constructor;
+  };
+}();
 
-      // if arrow element is not found, don't run the modifier
-      if (!arrow) {
-          return data;
-      }
 
-      // the arrow element must be child of its popper
-      if (!data.instance.popper.contains(arrow)) {
-          console.warn('WARNING: `arrowElement` must be child of its popper element!');
-          return data;
-      }
 
-      // arrow depends on keepTogether in order to work
-      if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {
-          console.warn('WARNING: keepTogether modifier is required by arrow modifier in order to work, be sure to include it before arrow!');
-          return data;
-      }
 
-      var arrowStyle = {};
-      var placement = data.placement.split('-')[0];
-      var popper = getPopperClientRect(data.offsets.popper);
-      var reference = data.offsets.reference;
-      var isVertical = ['left', 'right'].indexOf(placement) !== -1;
-
-      var len = isVertical ? 'height' : 'width';
-      var side = isVertical ? 'top' : 'left';
-      var altSide = isVertical ? 'left' : 'top';
-      var opSide = isVertical ? 'bottom' : 'right';
-      var arrowSize = getOuterSizes(arrow)[len];
-
-      //
-      // extends keepTogether behavior making sure the popper and its reference have enough pixels in conjuction
-      //
-
-      // top/left side
-      if (reference[opSide] - arrowSize < popper[side]) {
-          data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowSize);
-      }
-      // bottom/right side
-      if (reference[side] + arrowSize > popper[opSide]) {
-          data.offsets.popper[side] += reference[side] + arrowSize - popper[opSide];
+
+var defineProperty = function (obj, key, value) {
+  if (key in obj) {
+    Object.defineProperty(obj, key, {
+      value: value,
+      enumerable: true,
+      configurable: true,
+      writable: true
+    });
+  } else {
+    obj[key] = value;
+  }
+
+  return obj;
+};
+
+var _extends = Object.assign || function (target) {
+  for (var i = 1; i < arguments.length; i++) {
+    var source = arguments[i];
+
+    for (var key in source) {
+      if (Object.prototype.hasOwnProperty.call(source, key)) {
+        target[key] = source[key];
       }
+    }
+  }
 
-      // compute center of the popper
-      var center = reference[side] + reference[len] / 2 - arrowSize / 2;
+  return target;
+};
+
+/**
+ * Given the popper offsets, generate an output similar to getBoundingClientRect
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Object} popperOffsets
+ * @returns {Object} ClientRect like output
+ */
+function getClientRect(popperOffsets) {
+    return _extends({}, popperOffsets, {
+        right: popperOffsets.left + popperOffsets.width,
+        bottom: popperOffsets.top + popperOffsets.height
+    });
+}
+
+/**
+ * Get the outer sizes of the given element (offset size + margins)
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element
+ * @returns {Object} object containing width and height properties
+ */
+function getOuterSizes(element) {
+    var styles = window.getComputedStyle(element);
+    var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);
+    var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);
+    var result = {
+        width: element.offsetWidth + y,
+        height: element.offsetHeight + x
+    };
+    return result;
+}
+
+/**
+ * Get the opposite placement of the given one/
+ * @method
+ * @memberof Popper.Utils
+ * @argument {String} placement
+ * @returns {String} flipped placement
+ */
+function getOppositePlacement(placement) {
+  var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
+  return placement.replace(/left|right|bottom|top/g, function (matched) {
+    return hash[matched];
+  });
+}
+
+/**
+ * Get offsets to the popper
+ * @method
+ * @memberof Popper.Utils
+ * @param {Object} position - CSS position the Popper will get applied
+ * @param {HTMLElement} popper - the popper element
+ * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)
+ * @param {String} placement - one of the valid placement options
+ * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper
+ */
+function getPopperOffsets(position, popper, referenceOffsets, placement) {
+    placement = placement.split('-')[0];
+
+    // Get popper node sizes
+    var popperRect = getOuterSizes(popper);
+
+    // Add position, width and height to our offsets object
+    var popperOffsets = {
+        position: position,
+        width: popperRect.width,
+        height: popperRect.height
+    };
 
-      // Compute the sideValue using the updated popper offsets
-      var sideValue = center - getPopperClientRect(data.offsets.popper)[side];
+    // depending by the popper placement we have to compute its offsets slightly differently
+    var isHoriz = ['right', 'left'].indexOf(placement) !== -1;
+    var mainSide = isHoriz ? 'top' : 'left';
+    var secondarySide = isHoriz ? 'left' : 'top';
+    var measurement = isHoriz ? 'height' : 'width';
+    var secondaryMeasurement = !isHoriz ? 'height' : 'width';
+
+    popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;
+    if (placement === secondarySide) {
+        popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];
+    } else {
+        popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];
+    }
 
-      // prevent arrow from being placed not contiguously to its popper
-      sideValue = Math.max(Math.min(popper[len] - arrowSize, sideValue), 0);
-      arrowStyle[side] = sideValue;
-      arrowStyle[altSide] = ''; // make sure to remove any old style from the arrow
+    return popperOffsets;
+}
+
+/**
+ * Get offsets to the reference element
+ * @method
+ * @memberof Popper.Utils
+ * @param {Object} state
+ * @param {Element} popper - the popper element
+ * @param {Element} reference - the reference element (the popper will be relative to this)
+ * @returns {Object} An object containing the offsets which will be applied to the popper
+ */
+function getReferenceOffsets(state, popper, reference) {
+  var isParentFixed = state.position === 'fixed';
+  var isParentTransformed = state.isParentTransformed;
+  var offsetParent = getOffsetParent(isParentFixed && isParentTransformed ? reference : popper);
+
+  return getOffsetRectRelativeToCustomParent(reference, offsetParent, isParentFixed, isParentTransformed);
+}
+
+/**
+ * Get the prefixed supported property name
+ * @method
+ * @memberof Popper.Utils
+ * @argument {String} property (camelCase)
+ * @returns {String} prefixed property (camelCase)
+ */
+function getSupportedPropertyName(property) {
+    var prefixes = [false, 'ms', 'webkit', 'moz', 'o'];
+    var upperProp = property.charAt(0).toUpperCase() + property.slice(1);
+
+    for (var i = 0; i < prefixes.length - 1; i++) {
+        var prefix = prefixes[i];
+        var toCheck = prefix ? '' + prefix + upperProp : property;
+        if (typeof window.document.body.style[toCheck] !== 'undefined') {
+            return toCheck;
+        }
+    }
+    return null;
+}
+
+/**
+ * Check if the given variable is a function
+ * @method
+ * @memberof Popper.Utils
+ * @argument {*} functionToCheck - variable to check
+ * @returns {Boolean} answer to: is a function?
+ */
+function isFunction(functionToCheck) {
+  var getType = {};
+  return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
+}
+
+/**
+ * Helper used to know if the given modifier is enabled.
+ * @method
+ * @memberof Popper.Utils
+ * @returns {Boolean}
+ */
+function isModifierEnabled(modifiers, modifierName) {
+    return modifiers.some(function (_ref) {
+        var name = _ref.name,
+            enabled = _ref.enabled;
+        return enabled && name === modifierName;
+    });
+}
+
+/**
+ * Helper used to know if the given modifier depends from another one.
+ * It checks if the needed modifier is listed and enabled.
+ * @method
+ * @memberof Popper.Utils
+ * @param {Array} modifiers - list of modifiers
+ * @param {String} requestingName - name of requesting modifier
+ * @param {String} requestedName - name of requested modifier
+ * @returns {Boolean}
+ */
+function isModifierRequired(modifiers, requestingName, requestedName) {
+    var requesting = find(modifiers, function (_ref) {
+        var name = _ref.name;
+        return name === requestingName;
+    });
 
-      data.offsets.arrow = arrowStyle;
-      data.arrowElement = arrow;
+    return !!requesting && modifiers.some(function (modifier) {
+        return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;
+    });
+}
+
+/**
+ * Tells if a given input is a number
+ * @method
+ * @memberof Popper.Utils
+ * @param {*} input to check
+ * @return {Boolean}
+ */
+function isNumeric(n) {
+  return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);
+}
+
+/**
+ * Check if the given element has transforms applied to itself or a parent
+ * @method
+ * @memberof Popper.Utils
+ * @param  {Element} element
+ * @return {Boolean} answer to "isTransformed?"
+ */
+function isTransformed(element) {
+    if (element.nodeName === 'BODY') {
+        return false;
+    }
+    if (getStyleComputedProperty(element, 'transform') !== 'none') {
+        return true;
+    }
+    return getParentNode(element) ? isTransformed(getParentNode(element)) : element;
+}
+
+/**
+ * Remove event listeners used to update the popper position
+ * @method
+ * @memberof Popper.Utils
+ * @private
+ */
+function removeEventListeners(reference, state) {
+    // Remove resize event listener on window
+    window.removeEventListener('resize', state.updateBound);
+
+    // Remove scroll event listener on scroll parents
+    state.scrollParents.forEach(function (target) {
+        target.removeEventListener('scroll', state.updateBound);
+    });
 
-      return data;
-  }
+    // Reset state
+    state.updateBound = null;
+    state.scrollParents = [];
+    state.scrollElement = null;
+    state.eventsEnabled = false;
+    return state;
+}
+
+/**
+ * Loop trough the list of modifiers and run them in order, each of them will then edit the data object
+ * @method
+ * @memberof Popper.Utils
+ * @param {Object} data
+ * @param {Array} modifiers
+ * @param {Function} ends
+ */
+function runModifiers(modifiers, data, ends) {
+    var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));
+
+    modifiersToRun.forEach(function (modifier) {
+        if (modifier.enabled && isFunction(modifier.function)) {
+            data = modifier.function(data, modifier);
+        }
+    });
 
-  /**
-   * Get the opposite placement of the given one/
-   * @method
-   * @memberof Popper.Utils
-   * @argument {String} placement
-   * @returns {String} flipped placement
-   */
-  function getOppositePlacement(placement) {
-    var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
-    return placement.replace(/left|right|bottom|top/g, function (matched) {
-      return hash[matched];
+    return data;
+}
+
+/**
+ * Set the attributes to the given popper
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element - Element to apply the attributes to
+ * @argument {Object} styles - Object with a list of properties and values which will be applied to the element
+ */
+function setAttributes(element, attributes) {
+    Object.keys(attributes).forEach(function (prop) {
+        var value = attributes[prop];
+        if (value !== false) {
+            element.setAttribute(prop, attributes[prop]);
+        } else {
+            element.removeAttribute(prop);
+        }
     });
-  }
+}
+
+/**
+ * Set the style to the given popper
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element - Element to apply the style to
+ * @argument {Object} styles - Object with a list of properties and values which will be applied to the element
+ */
+function setStyles(element, styles) {
+    Object.keys(styles).forEach(function (prop) {
+        var unit = '';
+        // add unit if the value is numeric and is one of the following
+        if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {
+            unit = 'px';
+        }
+        element.style[prop] = styles[prop] + unit;
+    });
+}
 
-  /**
-   * Get the opposite placement variation of the given one/
-   * @method
-   * @memberof Popper.Utils
-   * @argument {String} placement variation
-   * @returns {String} flipped placement variation
-   */
-  function getOppositeVariation(variation) {
-      if (variation === 'end') {
-          return 'start';
-      } else if (variation === 'start') {
-          return 'end';
-      }
-      return variation;
-  }
+function attachToScrollParents(scrollParent, event, callback, scrollParents) {
+    var isBody = scrollParent.nodeName === 'BODY';
+    var target = isBody ? window : scrollParent;
+    target.addEventListener(event, callback, { passive: true });
 
-  /**
-   * Modifier used to flip the placement of the popper when the latter is starting overlapping its reference element.
-   * Requires the `preventOverflow` modifier before it in order to work.
-   * **NOTE:** data.instance modifier will run all its previous modifiers everytime it tries to flip the popper!
-   * @method
-   * @memberof Modifiers
-   * @argument {Object} data - The data object generated by update method
-   * @argument {Object} options - Modifiers configuration and options
-   * @returns {Object} The data object, properly modified
-   */
-  function flip(data, options) {
-      // check if preventOverflow is in the list of modifiers before the flip modifier.
-      // otherwise flip would not work as expected.
-      if (!isModifierRequired(data.instance.modifiers, 'flip', 'preventOverflow')) {
-          console.warn('WARNING: preventOverflow modifier is required by flip modifier in order to work, be sure to include it before flip!');
-          return data;
-      }
+    if (!isBody) {
+        attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);
+    }
+    scrollParents.push(target);
+}
+
+/**
+ * Setup needed event listeners used to update the popper position
+ * @method
+ * @memberof Popper.Utils
+ * @private
+ */
+function setupEventListeners(reference, options, state, updateBound) {
+    // Resize event listener on window
+    state.updateBound = updateBound;
+    window.addEventListener('resize', state.updateBound, { passive: true });
+
+    // Scroll event listener on scroll parents
+    var scrollElement = getScrollParent(reference);
+    attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);
+    state.scrollElement = scrollElement;
+    state.eventsEnabled = true;
+
+    return state;
+}
+
+/** @namespace Popper.Utils */
+var Utils = {
+    computeAutoPlacement: computeAutoPlacement,
+    debounce: debounce,
+    findIndex: findIndex,
+    getBordersSize: getBordersSize,
+    getBoundaries: getBoundaries,
+    getBoundingClientRect: getBoundingClientRect,
+    getClientRect: getClientRect,
+    getOffsetParent: getOffsetParent,
+    getOffsetRect: getOffsetRect,
+    getOffsetRectRelativeToCustomParent: getOffsetRectRelativeToCustomParent,
+    getOuterSizes: getOuterSizes,
+    getParentNode: getParentNode,
+    getPopperOffsets: getPopperOffsets,
+    getPosition: getPosition,
+    getReferenceOffsets: getReferenceOffsets,
+    getScroll: getScroll,
+    getScrollParent: getScrollParent,
+    getStyleComputedProperty: getStyleComputedProperty,
+    getSupportedPropertyName: getSupportedPropertyName,
+    getTotalScroll: getTotalScroll,
+    getWindowSizes: getWindowSizes,
+    includeScroll: includeScroll,
+    isFixed: isFixed,
+    isFunction: isFunction,
+    isModifierEnabled: isModifierEnabled,
+    isModifierRequired: isModifierRequired,
+    isNative: isNative,
+    isNumeric: isNumeric,
+    isTransformed: isTransformed,
+    removeEventListeners: removeEventListeners,
+    runModifiers: runModifiers,
+    setAttributes: setAttributes,
+    setStyles: setStyles,
+    setupEventListeners: setupEventListeners
+};
+
+/**
+ * Apply the computed styles to the popper element
+ * @method
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by `update` method
+ * @argument {Object} data.styles - List of style properties - values to apply to popper element
+ * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The same data object
+ */
+function applyStyle(data, options) {
+    // apply the final offsets to the popper
+    // NOTE: 1 DOM access here
+    var styles = {
+        position: data.offsets.popper.position
+    };
 
-      if (data.flipped && data.placement === data.originalPlacement) {
-          // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides
-          return data;
-      }
+    var attributes = {
+        'x-placement': data.placement
+    };
 
-      var placement = data.placement.split('-')[0];
-      var placementOpposite = getOppositePlacement(placement);
-      var variation = data.placement.split('-')[1] || '';
+    // round top and left to avoid blurry text
+    var left = Math.round(data.offsets.popper.left);
+    var top = Math.round(data.offsets.popper.top);
+
+    // if gpuAcceleration is set to true and transform is supported,
+    //  we use `translate3d` to apply the position to the popper we
+    // automatically use the supported prefixed version if needed
+    var prefixedProperty = getSupportedPropertyName('transform');
+    if (options.gpuAcceleration && prefixedProperty) {
+        styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
+        styles.top = 0;
+        styles.left = 0;
+        styles.willChange = 'transform';
+    }
+    // othwerise, we use the standard `left` and `top` properties
+    else {
+            styles.left = left;
+            styles.top = top;
+            styles.willChange = 'top, left';
+        }
+
+    // any property present in `data.styles` will be applied to the popper,
+    // in this way we can make the 3rd party modifiers add custom styles to it
+    // Be aware, modifiers could override the properties defined in the previous
+    // lines of this modifier!
+    setStyles(data.instance.popper, _extends({}, styles, data.styles));
+
+    // any property present in `data.attributes` will be applied to the popper,
+    // they will be set as HTML attributes of the element
+    setAttributes(data.instance.popper, _extends({}, attributes, data.attributes));
+
+    // if the arrow style has been computed, apply the arrow style
+    if (data.offsets.arrow) {
+        setStyles(data.arrowElement, data.offsets.arrow);
+    }
 
-      var flipOrder = [];
+    return data;
+}
+
+/**
+ * Set the x-placement attribute before everything else because it could be used to add margins to the popper
+ * margins needs to be calculated to get the correct popper offsets
+ * @method
+ * @memberof Popper.modifiers
+ * @param {HTMLElement} reference - The reference element used to position the popper
+ * @param {HTMLElement} popper - The HTML element used as popper.
+ * @param {Object} options - Popper.js options
+ */
+function applyStyleOnLoad(reference, popper, options, modifierOptions, state) {
+    // compute reference element offsets
+    var referenceOffsets = getReferenceOffsets(state, popper, reference);
+
+    // compute auto placement, store placement inside the data object,
+    // modifiers will be able to edit `placement` if needed
+    // and refer to originalPlacement to know the original value
+    options.placement = computeAutoPlacement(options.placement, referenceOffsets, popper);
+
+    popper.setAttribute('x-placement', options.placement);
+    return options;
+}
+
+/**
+ * Modifier used to move the arrowElements on the edge of the popper to make sure them are always between the popper and the reference element
+ * It will use the CSS outer size of the arrowElement element to know how many pixels of conjuction are needed
+ * @method
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function arrow(data, options) {
+    // arrow depends on keepTogether in order to work
+    if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {
+        console.warn('WARNING: `keepTogether` modifier is required by arrow modifier in order to work, be sure to include it before `arrow`!');
+        return data;
+    }
 
-      if (options.behavior === 'flip') {
-          flipOrder = [placement, placementOpposite];
-      } else {
-          flipOrder = options.behavior;
-      }
+    var arrowElement = options.element;
+
+    // if arrowElement is a string, suppose it's a CSS selector
+    if (typeof arrowElement === 'string') {
+        arrowElement = data.instance.popper.querySelector(arrowElement);
+
+        // if arrowElement is not found, don't run the modifier
+        if (!arrowElement) {
+            return data;
+        }
+    } else {
+        // if the arrowElement isn't a query selector we must check that the
+        // provided DOM node is child of its popper node
+        if (!data.instance.popper.contains(arrowElement)) {
+            console.warn('WARNING: `arrow.element` must be child of its popper element!');
+            return data;
+        }
+    }
 
-      flipOrder.forEach(function (step, index) {
-          if (placement !== step || flipOrder.length === index + 1) {
-              return data;
-          }
+    var placement = data.placement.split('-')[0];
+    var popper = getClientRect(data.offsets.popper);
+    var reference = data.offsets.reference;
+    var isVertical = ['left', 'right'].indexOf(placement) !== -1;
 
-          placement = data.placement.split('-')[0];
-          placementOpposite = getOppositePlacement(placement);
+    var len = isVertical ? 'height' : 'width';
+    var side = isVertical ? 'top' : 'left';
+    var altSide = isVertical ? 'left' : 'top';
+    var opSide = isVertical ? 'bottom' : 'right';
+    var arrowElementSize = getOuterSizes(arrowElement)[len];
 
-          var popperOffsets = getPopperClientRect(data.offsets.popper);
+    //
+    // extends keepTogether behavior making sure the popper and its reference have enough pixels in conjuction
+    //
 
-          // this boolean is used to distinguish right and bottom from top and left
-          // they need different computations to get flipped
-          var a = ['right', 'bottom'].indexOf(placement) !== -1;
-          var b = ['top', 'bottom'].indexOf(placement) !== -1;
+    // top/left side
+    if (reference[opSide] - arrowElementSize < popper[side]) {
+        data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);
+    }
+    // bottom/right side
+    if (reference[side] + arrowElementSize > popper[opSide]) {
+        data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];
+    }
 
-          // using Math.floor because the reference offsets may contain decimals we are not going to consider here
-          var flippedPosition = a && Math.floor(data.offsets.reference[placement]) > Math.floor(popperOffsets[placementOpposite]) || !a && Math.floor(data.offsets.reference[placement]) < Math.floor(popperOffsets[placementOpposite]);
+    // compute center of the popper
+    var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;
+
+    // Compute the sideValue using the updated popper offsets
+    var sideValue = center - getClientRect(data.offsets.popper)[side];
+
+    // prevent arrowElement from being placed not contiguously to its popper
+    sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);
+
+    data.arrowElement = arrowElement;
+    data.offsets.arrow = {};
+    data.offsets.arrow[side] = sideValue;
+    data.offsets.arrow[altSide] = ''; // make sure to unset any eventual altSide value from the DOM node
+
+    return data;
+}
+
+/**
+ * Get the opposite placement variation of the given one/
+ * @method
+ * @memberof Popper.Utils
+ * @argument {String} placement variation
+ * @returns {String} flipped placement variation
+ */
+function getOppositeVariation(variation) {
+    if (variation === 'end') {
+        return 'start';
+    } else if (variation === 'start') {
+        return 'end';
+    }
+    return variation;
+}
+
+/**
+ * Modifier used to flip the placement of the popper when the latter is starting overlapping its reference element.
+ * Requires the `preventOverflow` modifier before it in order to work.
+ * **NOTE:** data.instance modifier will run all its previous modifiers everytime it tries to flip the popper!
+ * @method
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function flip(data, options) {
+    // if `inner` modifier is enabled, we can't use the `flip` modifier
+    if (isModifierEnabled(data.instance.modifiers, 'inner')) {
+        return data;
+    }
 
-          var flippedVariation = options.flipVariations && (b && variation === 'start' && Math.floor(popperOffsets.left) < Math.floor(data.boundaries.left) || b && variation === 'end' && Math.floor(popperOffsets.right) > Math.floor(data.boundaries.right) || !b && variation === 'start' && Math.floor(popperOffsets.top) < Math.floor(data.boundaries.top) || !b && variation === 'end' && Math.floor(popperOffsets.bottom) > Math.floor(data.boundaries.bottom));
+    if (data.flipped && data.placement === data.originalPlacement) {
+        // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides
+        return data;
+    }
 
-          if (flippedPosition || flippedVariation) {
-              // this boolean to detect any flip loop
-              data.flipped = true;
+    var boundaries = getBoundaries(data.instance.popper, options.padding, options.boundariesElement);
 
-              if (flippedPosition) {
-                  placement = flipOrder[index + 1];
-              }
-              if (flippedVariation) {
-                  variation = getOppositeVariation(variation);
-              }
+    var placement = data.placement.split('-')[0];
+    var placementOpposite = getOppositePlacement(placement);
+    var variation = data.placement.split('-')[1] || '';
 
-              data.placement = placement + (variation ? '-' + variation : '');
-              data.offsets.popper = getOffsets(data.instance.state, data.instance.popper, data.instance.reference, data.placement).popper;
+    var flipOrder = [];
 
-              data = runModifiers(data.instance.modifiers, data.instance.options, data, 'flip');
-          }
-      });
-      return data;
-  }
+    if (options.behavior === 'flip') {
+        flipOrder = [placement, placementOpposite];
+    } else {
+        flipOrder = options.behavior;
+    }
 
-  /**
-   * Modifier used to make sure the popper is always near its reference element
-   * It cares only about the first axis, you can still have poppers with margin
-   * between the popper and its reference element.
-   * @method
-   * @memberof Modifiers
-   * @argument {Object} data - The data object generated by update method
-   * @argument {Object} options - Modifiers configuration and options
-   * @returns {Object} The data object, properly modified
-   */
-  function keepTogether(data) {
-      var popper = getPopperClientRect(data.offsets.popper);
-      var reference = data.offsets.reference;
-      var f = Math.floor;
-      var placement = data.placement.split('-')[0];
-
-      if (['top', 'bottom'].indexOf(placement) !== -1) {
-          if (popper.right < f(reference.left)) {
-              data.offsets.popper.left = f(reference.left) - popper.width;
-          }
-          if (popper.left > f(reference.right)) {
-              data.offsets.popper.left = f(reference.right);
-          }
-      } else {
-          if (popper.bottom < f(reference.top)) {
-              data.offsets.popper.top = f(reference.top) - popper.height;
-          }
-          if (popper.top > f(reference.bottom)) {
-              data.offsets.popper.top = f(reference.bottom);
-          }
-      }
+    flipOrder.forEach(function (step, index) {
+        if (placement !== step || flipOrder.length === index + 1) {
+            return data;
+        }
 
-      return data;
-  }
+        placement = data.placement.split('-')[0];
+        placementOpposite = getOppositePlacement(placement);
 
-  /**
-   * Modifier used to add an offset to the popper, useful if you more granularity positioning your popper.
-   * The offsets will shift the popper on the side of its reference element.
-   * @method
-   * @memberof Modifiers
-   * @argument {Object} data - The data object generated by update method
-   * @argument {Object} options - Modifiers configuration and options
-   * @argument {Number|String} options.offset=0
-   *      Basic usage allows a number used to nudge the popper by the given amount of pixels.
-   *      You can pass a percentage value as string (eg. `20%`) to nudge by the given percentage (relative to reference element size)
-   *      Other supported units are `vh` and `vw` (relative to viewport)
-   *      Additionally, you can pass a pair of values (eg. `10 20` or `2vh 20%`) to nudge the popper
-   *      on both axis.
-   *      A note about percentage values, if you want to refer a percentage to the popper size instead of the reference element size,
-   *      use `%p` instead of `%` (eg: `20%p`). To make it clearer, you can replace `%` with `%r` and use eg.`10%p 25%r`.
-   *      > **Heads up!** The order of the axis is relative to the popper placement: `bottom` or `top` are `X,Y`, the other are `Y,X`
-   * @returns {Object} The data object, properly modified
-   */
-  function offset(data, options) {
-      var placement = data.placement;
-      var popper = data.offsets.popper;
-
-      var offsets = void 0;
-      if (isNumeric(options.offset)) {
-          offsets = [options.offset, 0];
-      } else {
-          // split the offset in case we are providing a pair of offsets separated
-          // by a blank space
-          offsets = options.offset.split(' ');
-
-          // itherate through each offset to compute them in case they are percentages
-          offsets = offsets.map(function (offset, index) {
-              // separate value from unit
-              var split = offset.match(/(\d*\.?\d*)(.*)/);
-              var value = +split[1];
-              var unit = split[2];
-
-              // use height if placement is left or right and index is 0
-              // otherwise use height
-              // in this way the first offset will use an axis and the second one
-              // will use the other one
-              var useHeight = placement.indexOf('right') !== -1 || placement.indexOf('left') !== -1;
-
-              if (index === 1) {
-                  useHeight = !useHeight;
-              }
-
-              // if is a percentage, we calculate the value of it using as base the
-              // sizes of the reference element
-              if (unit === '%' || unit === '%r') {
-                  var referenceRect = getPopperClientRect(data.offsets.reference);
-                  var len = void 0;
-                  if (useHeight) {
-                      len = referenceRect.height;
-                  } else {
-                      len = referenceRect.width;
-                  }
-                  return len / 100 * value;
-              }
-              // if is a percentage relative to the popper, we calculate the value of it using
-              // as base the sizes of the popper
-              else if (unit === '%p') {
-                      var popperRect = getPopperClientRect(data.offsets.popper);
-                      var _len = void 0;
-                      if (useHeight) {
-                          _len = popperRect.height;
-                      } else {
-                          _len = popperRect.width;
-                      }
-                      return _len / 100 * value;
-                  }
-                  // if is a vh or vw, we calculate the size based on the viewport
-                  else if (unit === 'vh' || unit === 'vw') {
-                          var size = void 0;
-                          if (unit === 'vh') {
-                              size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
-                          } else {
-                              size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
-                          }
-                          return size / 100 * value;
-                      }
-                      // if is an explicit pixel unit, we get rid of the unit and keep the value
-                      else if (unit === 'px') {
-                              return +value;
-                          }
-                          // if is an implicit unit, it's px, and we return just the value
-                          else {
-                                  return +offset;
-                              }
-          });
-      }
+        var popperOffsets = getClientRect(data.offsets.popper);
+        var refOffsets = data.offsets.reference;
 
-      if (data.placement.indexOf('left') !== -1) {
-          popper.top += offsets[0];
-          popper.left -= offsets[1] || 0;
-      } else if (data.placement.indexOf('right') !== -1) {
-          popper.top += offsets[0];
-          popper.left += offsets[1] || 0;
-      } else if (data.placement.indexOf('top') !== -1) {
-          popper.left += offsets[0];
-          popper.top -= offsets[1] || 0;
-      } else if (data.placement.indexOf('bottom') !== -1) {
-          popper.left += offsets[0];
-          popper.top += offsets[1] || 0;
-      }
-      return data;
-  }
+        // using floor because the reference offsets may contain decimals we are not going to consider here
+        var floor = Math.floor;
+        var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);
 
-  /**
-   * Modifier used to make sure the popper does not overflows from it's boundaries
-   * @method
-   * @memberof Modifiers
-   * @argument {Object} data - The data object generated by `update` method
-   * @argument {Object} options - Modifiers configuration and options
-   * @returns {Object} The data object, properly modified
-   */
-  function preventOverflow(data, options) {
-      function shouldMoveWithTarget(direction) {
-          if (!options.moveWithTarget) {
-              return false;
-          }
-          var placement = data.originalPlacement.split('-')[0];
-
-          if (data.flipped && placement === direction || placement === getOppositePlacement(direction)) {
-              return true;
-          }
-          if (placement !== direction && placement !== getOppositePlacement(direction)) {
-              return true;
-          }
-
-          return false;
-      }
-      var order = options.priority;
-      var popper = getPopperClientRect(data.offsets.popper);
-
-      var check = {
-          left: function left() {
-              var left = popper.left;
-              if (popper.left < data.boundaries.left && !shouldMoveWithTarget('left')) {
-                  left = Math.max(popper.left, data.boundaries.left);
-              }
-              return { left: left };
-          },
-          right: function right() {
-              var left = popper.left;
-              if (popper.right > data.boundaries.right && !shouldMoveWithTarget('right')) {
-                  left = Math.min(popper.left, data.boundaries.right - popper.width);
-              }
-              return { left: left };
-          },
-          top: function top() {
-              var top = popper.top;
-              if (popper.top < data.boundaries.top && !shouldMoveWithTarget('top')) {
-                  top = Math.max(popper.top, data.boundaries.top);
-              }
-              return { top: top };
-          },
-          bottom: function bottom() {
-              var top = popper.top;
-              if (popper.bottom > data.boundaries.bottom && !shouldMoveWithTarget('bottom')) {
-                  top = Math.min(popper.top, data.boundaries.bottom - popper.height);
-              }
-              return { top: top };
-          }
-      };
-
-      order.forEach(function (direction) {
-          data.offsets.popper = Object.assign(popper, check[direction]());
-      });
-
-      return data;
-  }
+        var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);
+        var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);
+        var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);
+        var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);
 
-  /**
-   * Modifier used to shift the popper on the start or end of its reference element side
-   * @method
-   * @memberof Modifiers
-   * @argument {Object} data - The data object generated by `update` method
-   * @argument {Object} options - Modifiers configuration and options
-   * @returns {Object} The data object, properly modified
-   */
-  function shift(data) {
-      var placement = data.placement;
-      var basePlacement = placement.split('-')[0];
-      var shiftvariation = placement.split('-')[1];
-
-      // if shift shiftvariation is specified, run the modifier
-      if (shiftvariation) {
-          var reference = data.offsets.reference;
-          var popper = getPopperClientRect(data.offsets.popper);
-
-          var shiftOffsets = {
-              y: {
-                  start: { top: reference.top },
-                  end: { top: reference.top + reference.height - popper.height }
-              },
-              x: {
-                  start: { left: reference.left },
-                  end: { left: reference.left + reference.width - popper.width }
-              }
-          };
-
-          var axis = ['bottom', 'top'].indexOf(basePlacement) !== -1 ? 'x' : 'y';
-
-          data.offsets.popper = Object.assign(popper, shiftOffsets[axis][shiftvariation]);
-      }
+        var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;
 
-      return data;
-  }
+        // flip the variation if required
+        var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
+        var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);
 
-  /**
-   * Modifier used to hide the popper when its reference element is outside of the
-   * popper boundaries. It will set an x-hidden attribute which can be used to hide
-   * the popper when its reference is out of boundaries.
-   * @method
-   * @memberof Modifiers
-   * @argument {Object} data - The data object generated by update method
-   * @argument {Object} options - Modifiers configuration and options
-   * @returns {Object} The data object, properly modified
-   */
-  function hide(data) {
-      var refRect = data.offsets.reference;
-      var bound = data.boundaries;
-
-      if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {
-          data.hide = true;
-          data.instance.popper.setAttribute('x-out-of-boundaries', '');
-      } else {
-          data.hide = false;
-          data.instance.popper.removeAttribute('x-out-of-boundaries');
-      }
+        if (overlapsRef || overflowsBoundaries || flippedVariation) {
+            // this boolean to detect any flip loop
+            data.flipped = true;
 
-      return data;
-  }
+            if (overlapsRef || overflowsBoundaries) {
+                placement = flipOrder[index + 1];
+            }
 
-  /**
-   * Modifiers are plugins used to alter the behavior of your poppers.
-   * Popper.js uses a set of 7 modifiers to provide all the basic functionalities
-   * needed by the library.
-   *
-   * Each modifier is an object containing several properties listed below.
-   * @namespace Modifiers
-   * @param {Object} modifier - Modifier descriptor
-   * @param {Integer} modifier.order
-   *      The `order` property defines the execution order of the modifiers.
-   *      The built-in modifiers have orders with a gap of 100 units in between,
-   *      this allows you to inject additional modifiers between the existing ones
-   *      without having to redefine the order of all of them.
-   *      The modifiers are executed starting from the one with the lowest order.
-   * @param {Boolean} modifier.enabled - When `true`, the modifier will be used.
-   * @param {Modifiers~modifier} modifier.function - Modifier function.
-   * @param {Modifiers~onLoad} modifier.onLoad - Function executed on popper initalization
-   * @return {Object} data - Each modifier must return the modified `data` object.
-   */
-
-  var modifiersFunctions = {
-    applyStyle: applyStyle,
-    arrow: arrow,
-    flip: flip,
-    keepTogether: keepTogether,
-    offset: offset,
-    preventOverflow: preventOverflow,
-    shift: shift,
-    hide: hide
-  };
+            if (flippedVariation) {
+                variation = getOppositeVariation(variation);
+            }
 
-  var modifiersOnLoad = {
-    applyStyleOnLoad: applyStyleOnLoad
-  };
+            data.placement = placement + (variation ? '-' + variation : '');
+            data.offsets.popper = getPopperOffsets(data.instance.state.position, data.instance.popper, data.offsets.reference, data.placement);
 
-  /**
-   * Modifiers can edit the `data` object to change the beheavior of the popper.
-   * This object contains all the informations used by Popper.js to compute the
-   * popper position.
-   * The modifier can edit the data as needed, and then `return` it as result.
-   *
-   * @callback Modifiers~modifier
-   * @param {dataObject} data
-   * @return {dataObject} modified data
-   */
-
-  /**
-   * The `dataObject` is an object containing all the informations used by Popper.js
-   * this object get passed to modifiers and to the `onCreate` and `onUpdate` callbacks.
-   * @name dataObject
-   * @property {Object} data.instance The Popper.js instance
-   * @property {String} data.placement Placement applied to popper
-   * @property {String} data.originalPlacement Placement originally defined on init
-   * @property {Boolean} data.flipped True if popper has been flipped by flip modifier
-   * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper.
-   * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier
-   * @property {Object} data.styles Any CSS property defined here will be applied to the popper, it expects the JavaScript nomenclature (eg. `marginBottom`)
-   * @property {Object} data.boundaries Offsets of the popper boundaries
-   * @property {Object} data.offsets The measurements of popper, reference and arrow elements.
-   * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values
-   * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values
-   * @property {Object} data.offsets.arro] `top` and `left` offsets, only one of them will be different from 0
-   */
-
-  var classCallCheck = function (instance, Constructor) {
-    if (!(instance instanceof Constructor)) {
-      throw new TypeError("Cannot call a class as a function");
+            data = runModifiers(data.instance.modifiers, data, 'flip');
+        }
+    });
+    return data;
+}
+
+/**
+ * Modifier used to make sure the popper is always near its reference element
+ * It cares only about the first axis, you can still have poppers with margin
+ * between the popper and its reference element.
+ * @method
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function keepTogether(data) {
+    var popper = getClientRect(data.offsets.popper);
+    var reference = data.offsets.reference;
+    var placement = data.placement.split('-')[0];
+    var floor = Math.floor;
+    var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
+    var side = isVertical ? 'right' : 'bottom';
+    var opSide = isVertical ? 'left' : 'top';
+    var measurement = isVertical ? 'width' : 'height';
+
+    if (popper[side] < floor(reference[opSide])) {
+        data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];
+    }
+    if (popper[opSide] > floor(reference[side])) {
+        data.offsets.popper[opSide] = floor(reference[side]);
     }
-  };
 
-  var createClass = function () {
-    function defineProperties(target, props) {
-      for (var i = 0; i < props.length; i++) {
-        var descriptor = props[i];
-        descriptor.enumerable = descriptor.enumerable || false;
-        descriptor.configurable = true;
-        if ("value" in descriptor) descriptor.writable = true;
-        Object.defineProperty(target, descriptor.key, descriptor);
-      }
+    return data;
+}
+
+/**
+ * Modifier used to add an offset to the popper, useful if you more granularity positioning your popper.
+ * The offsets will shift the popper on the side of its reference element.
+ * @method
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @argument {Number|String} options.offset=0
+ *      Basic usage allows a number used to nudge the popper by the given amount of pixels.
+ *      You can pass a percentage value as string (eg. `20%`) to nudge by the given percentage (relative to reference element size)
+ *      Other supported units are `vh` and `vw` (relative to viewport)
+ *      Additionally, you can pass a pair of values (eg. `10 20` or `2vh 20%`) to nudge the popper
+ *      on both axis.
+ *      A note about percentage values, if you want to refer a percentage to the popper size instead of the reference element size,
+ *      use `%p` instead of `%` (eg: `20%p`). To make it clearer, you can replace `%` with `%r` and use eg.`10%p 25%r`.
+ *      > **Heads up!** The order of the axis is relative to the popper placement: `bottom` or `top` are `X,Y`, the other are `Y,X`
+ * @returns {Object} The data object, properly modified
+ */
+function offset(data, options) {
+    var placement = data.placement;
+    var popper = data.offsets.popper;
+
+    var offsets = void 0;
+    if (isNumeric(options.offset)) {
+        offsets = [options.offset, 0];
+    } else {
+        // split the offset in case we are providing a pair of offsets separated
+        // by a blank space
+        offsets = options.offset.split(' ');
+
+        // itherate through each offset to compute them in case they are percentages
+        offsets = offsets.map(function (offset, index) {
+            // separate value from unit
+            var split = offset.match(/(\d*\.?\d*)(.*)/);
+            var value = +split[1];
+            var unit = split[2];
+
+            // use height if placement is left or right and index is 0 otherwise use width
+            // in this way the first offset will use an axis and the second one
+            // will use the other one
+            var useHeight = placement.indexOf('right') !== -1 || placement.indexOf('left') !== -1;
+
+            if (index === 1) {
+                useHeight = !useHeight;
+            }
+
+            var measurement = useHeight ? 'height' : 'width';
+
+            // if is a percentage relative to the popper (%p), we calculate the value of it using
+            // as base the sizes of the popper
+            // if is a percentage (% or %r), we calculate the value of it using as base the
+            // sizes of the reference element
+            if (unit.indexOf('%') === 0) {
+                var element = void 0;
+                switch (unit) {
+                    case '%p':
+                        element = data.offsets.popper;
+                        break;
+                    case '%':
+                    case '$r':
+                    default:
+                        element = data.offsets.reference;
+                }
+
+                var rect = getClientRect(element);
+                var len = rect[measurement];
+                return len / 100 * value;
+            }
+            // if is a vh or vw, we calculate the size based on the viewport
+            else if (unit === 'vh' || unit === 'vw') {
+                    var size = void 0;
+                    if (unit === 'vh') {
+                        size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
+                    } else {
+                        size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
+                    }
+                    return size / 100 * value;
+                }
+                // if is an explicit pixel unit, we get rid of the unit and keep the value
+                else if (unit === 'px') {
+                        return +value;
+                    }
+                    // if is an implicit unit, it's px, and we return just the value
+                    else {
+                            return +offset;
+                        }
+        });
     }
 
-    return function (Constructor, protoProps, staticProps) {
-      if (protoProps) defineProperties(Constructor.prototype, protoProps);
-      if (staticProps) defineProperties(Constructor, staticProps);
-      return Constructor;
+    if (data.placement.indexOf('left') !== -1) {
+        popper.top += offsets[0];
+        popper.left -= offsets[1] || 0;
+    } else if (data.placement.indexOf('right') !== -1) {
+        popper.top += offsets[0];
+        popper.left += offsets[1] || 0;
+    } else if (data.placement.indexOf('top') !== -1) {
+        popper.left += offsets[0];
+        popper.top -= offsets[1] || 0;
+    } else if (data.placement.indexOf('bottom') !== -1) {
+        popper.left += offsets[0];
+        popper.top += offsets[1] || 0;
+    }
+    return data;
+}
+
+/**
+ * Modifier used to prevent the popper from being positioned outside the boundary.
+ *
+ * An scenario exists where the reference itself is not within the boundaries. We can
+ * say it has "escaped the boundaries" — or just "escaped". In this case we need to
+ * decide whether the popper should either:
+ *
+ * - detach from the reference and remain "trapped" in the boundaries, or
+ * - if it should be ignore the boundary and "escape with the reference"
+ *
+ * When `escapeWithReference` is `true`, and reference is completely outside the
+ * boundaries, the popper will overflow (or completely leave) the boundaries in order
+ * to remain attached to the edge of the reference.
+ *
+ * @method
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by `update` method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function preventOverflow(data, options) {
+    var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);
+    var boundaries = getBoundaries(data.instance.popper, options.padding, boundariesElement);
+    options.boundaries = boundaries;
+
+    var order = options.priority;
+    var popper = getClientRect(data.offsets.popper);
+
+    var check = {
+        primary: function primary(placement) {
+            var value = popper[placement];
+            if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {
+                value = Math.max(popper[placement], boundaries[placement]);
+            }
+            return defineProperty({}, placement, value);
+        },
+        secondary: function secondary(placement) {
+            var mainSide = placement === 'right' ? 'left' : 'top';
+            var value = popper[mainSide];
+            if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {
+                value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));
+            }
+            return defineProperty({}, mainSide, value);
+        }
     };
-  }();
-
-  // default options
-  var DEFAULTS = {
-      // placement of the popper
-      placement: 'bottom',
-
-      // if true, it uses the CSS 3d transformation to position the popper
-      gpuAcceleration: true,
-
-      // the element which will act as boundary of the popper
-      boundariesElement: 'viewport',
-
-      // amount of pixel used to define a minimum distance between the boundaries and the popper
-      boundariesPadding: 5,
-
-      // list of functions used to modify the offsets before they are applied to the popper
-      modifiers: {
-          shift: {
-              order: 100,
-              enabled: true,
-              function: modifiersFunctions.shift
-          },
-          offset: {
-              order: 200,
-              enabled: true,
-              function: modifiersFunctions.offset,
-              // nudges popper from its origin by the given amount of pixels (can be negative)
-              offset: 0
-          },
-          preventOverflow: {
-              order: 300,
-              enabled: true,
-              function: modifiersFunctions.preventOverflow,
-              // popper will try to prevent overflow following these priorities
-              //  by default, then, it could overflow on the left and on top of the boundariesElement
-              priority: ['left', 'right', 'top', 'bottom']
-          },
-          keepTogether: {
-              order: 400,
-              enabled: true,
-              function: modifiersFunctions.keepTogether
-          },
-          arrow: {
-              order: 500,
-              enabled: true,
-              function: modifiersFunctions.arrow,
-              // selector or node used as arrow
-              element: '[x-arrow]'
-          },
-          flip: {
-              order: 600,
-              enabled: true,
-              function: modifiersFunctions.flip,
-              // the behavior used to change the popper's placement
-              behavior: 'flip'
-          },
-          hide: {
-              order: 700,
-              enabled: true,
-              function: modifiersFunctions.hide
-          },
-          applyStyle: {
-              order: 800,
-              enabled: true,
-              function: modifiersFunctions.applyStyle,
-              onLoad: modifiersOnLoad.applyStyleOnLoad
-          }
-      }
-  };
 
-  /**
-   * Create a new Popper.js instance
-   * @class Popper
-   * @param {HTMLElement} reference - The reference element used to position the popper
-   * @param {HTMLElement} popper - The HTML element used as popper.
-   * @param {Object} options
-   * @param {String} options.placement=bottom
-   *      Placement of the popper accepted values: `top(-start, -end), right(-start, -end), bottom(-start, -right),
-   *      left(-start, -end)`
-   *
-   * @param {Boolean} options.gpuAcceleration=true
-   *      When this property is set to true, the popper position will be applied using CSS3 translate3d, allowing the
-   *      browser to use the GPU to accelerate the rendering.
-   *      If set to false, the popper will be placed using `top` and `left` properties, not using the GPU.
-   *
-   * @param {String|Element} options.boundariesElement='viewport'
-   *      The element which will define the boundaries of the popper position, the popper will never be placed outside
-   *      of the defined boundaries (except if `keepTogether` is enabled)
-   *
-   * @param {Number} options.boundariesPadding=5
-   *      Additional padding for the boundaries
-   *
-   * @param {Boolean} options.removeOnDestroy=false
-   *      Set to true if you want to automatically remove the popper when you call the `destroy` method.
-   *
-   * @param {Object} options.modifiers
-   *      List of functions used to modify the data before they are applied to the popper (see source code for default values)
-   *
-   * @param {Object} options.modifiers.arrow - Arrow modifier configuration
-   * @param {HTMLElement|String} options.modifiers.arrow.element='[x-arrow]'
-   *      The DOM Node used as arrow for the popper, or a CSS selector used to get the DOM node. It must be child of
-   *      its parent Popper. Popper.js will apply to the given element the style required to align the arrow with its
-   *      reference element.
-   *      By default, it will look for a child node of the popper with the `x-arrow` attribute.
-   *
-   * @param {Object} options.modifiers.offset - Offset modifier configuration
-   * @param {Number} options.modifiers.offset.offset=0
-   *      Amount of pixels the popper will be shifted (can be negative).
-   *
-   * @param {Object} options.modifiers.preventOverflow - PreventOverflow modifier configuration
-   * @param {Array} [options.modifiers.preventOverflow.priority=['left', 'right', 'top', 'bottom']]
-   *      Priority used when Popper.js tries to avoid overflows from the boundaries, they will be checked in order,
-   *      this means that the last one will never overflow
-   *
-   * @param {Object} options.modifiers.flip - Flip modifier configuration
-   * @param {String|Array} options.modifiers.flip.behavior='flip'
-   *      The behavior used by the `flip` modifier to change the placement of the popper when the latter is trying to
-   *      overlap its reference element. Defining `flip` as value, the placement will be flipped on
-   *      its axis (`right - left`, `top - bottom`).
-   *      You can even pass an array of placements (eg: `['right', 'left', 'top']` ) to manually specify
-   *      how alter the placement when a flip is needed. (eg. in the above example, it would first flip from right to left,
-   *      then, if even in its new placement, the popper is overlapping its reference element, it will be moved to top)
-   *
-   * @return {Object} instance - The generated Popper.js instance
-   */
-
-  var Popper = function () {
-      function Popper(reference, popper) {
-          var _this = this;
-
-          var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
-          classCallCheck(this, Popper);
-          this.Defaults = DEFAULTS;
-
-          // init state
-          this.state = {
-              isDestroyed: false
-          };
-
-          // get reference and popper elements (allow jQuery wrappers)
-          this.reference = reference.jquery ? reference[0] : reference;
-          this.popper = popper.jquery ? popper[0] : popper;
-
-          // with {} we create a new object with the options inside it
-          this.options = Object.assign({}, DEFAULTS, options);
-
-          // refactoring modifiers' list (Object => Array)
-          this.modifiers = Object.keys(DEFAULTS.modifiers).map(function (name) {
-              return Object.assign({ name: name }, DEFAULTS.modifiers[name]);
-          });
-
-          // assign default values to modifiers, making sure to override them with
-          // the ones defined by user
-          this.modifiers = this.modifiers.map(function (defaultConfig) {
-              var userConfig = options.modifiers && options.modifiers[defaultConfig.name] || {};
-              var finalConfig = Object.assign({}, defaultConfig, userConfig);
-              return finalConfig;
-          });
-
-          // add custom modifiers to the modifiers list
-          if (options.modifiers) {
-              Object.keys(options.modifiers).forEach(function (name) {
-                  // take in account only custom modifiers
-                  if (DEFAULTS.modifiers[name] === undefined) {
-                      var modifier = options.modifiers[name];
-                      modifier.name = name;
-                      _this.modifiers.push(modifier);
-                  }
-              });
-          }
-
-          // sort the modifiers by order
-          this.modifiers = this.modifiers.sort(sortModifiers);
-
-          // modifiers have the ability to execute arbitrary code when Popper.js get inited
-          // such code is executed in the same order of its modifier
-          this.modifiers.forEach(function (modifier) {
-              if (modifier.enabled && isFunction(modifier.onLoad)) {
-                  modifier.onLoad(_this.reference, _this.popper, _this.options);
-              }
-          });
-
-          // get the popper position type
-          this.state.position = getPosition(this.popper, this.reference);
-
-          // determine how we should set the origin of offsets
-          this.state.isParentTransformed = isTransformed(this.popper.parentNode);
-
-          // fire the first update to position the popper in the right place
-          this.update(true);
-
-          // setup event listeners, they will take care of update the position in specific situations
-          setupEventListeners(this.reference, this.options, this.state, function () {
-              return _this.update();
-          });
-
-          // make it chainable
-          return this;
-      }
+    order.forEach(function (placement) {
+        var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
+        popper = _extends({}, popper, check[side](placement));
+    });
+
+    data.offsets.popper = popper;
+
+    return data;
+}
+
+/**
+ * Modifier used to shift the popper on the start or end of its reference element side
+ * @method
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by `update` method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function shift(data) {
+    var placement = data.placement;
+    var basePlacement = placement.split('-')[0];
+    var shiftvariation = placement.split('-')[1];
+
+    // if shift shiftvariation is specified, run the modifier
+    if (shiftvariation) {
+        var reference = data.offsets.reference;
+        var popper = getClientRect(data.offsets.popper);
+        var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;
+        var side = isVertical ? 'left' : 'top';
+        var measurement = isVertical ? 'width' : 'height';
+
+        var shiftOffsets = {
+            start: defineProperty({}, side, reference[side]),
+            end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])
+        };
+
+        data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);
+    }
+
+    return data;
+}
+
+/**
+ * Modifier used to hide the popper when its reference element is outside of the
+ * popper boundaries. It will set an x-hidden attribute which can be used to hide
+ * the popper when its reference is out of boundaries.
+ * @method
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function hide(data) {
+    if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {
+        console.warn('WARNING: preventOverflow modifier is required by hide modifier in order to work, be sure to include it before hide!');
+        return data;
+    }
+
+    var refRect = data.offsets.reference;
+    var bound = find(data.instance.modifiers, function (modifier) {
+        return modifier.name === 'preventOverflow';
+    }).boundaries;
+
+    if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {
+        // Avoid unnecessary DOM access if visibility hasn't changed
+        if (data.hide === true) {
+            return data;
+        }
+
+        data.hide = true;
+        data.attributes['x-out-of-boundaries'] = '';
+    } else {
+        // Avoid unnecessary DOM access if visibility hasn't changed
+        if (data.hide === false) {
+            return data;
+        }
+
+        data.hide = false;
+        data.attributes['x-out-of-boundaries'] = false;
+    }
+
+    return data;
+}
+
+/**
+ * Modifier used to make the popper flow toward the inner of the reference element.
+ * By default, when this modifier is disabled, the popper will be placed outside
+ * the reference element.
+ * @method
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by `update` method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function inner(data) {
+    var placement = data.placement;
+    var basePlacement = placement.split('-')[0];
+    var popper = getClientRect(data.offsets.popper);
+    var reference = getClientRect(data.offsets.reference);
+    var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;
+
+    var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;
+
+    popper[isHoriz ? 'left' : 'top'] = reference[placement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);
+
+    data.placement = getOppositePlacement(placement);
+    data.offsets.popper = getClientRect(popper);
+
+    return data;
+}
+
+/**
+ * Modifiers are plugins used to alter the behavior of your poppers.
+ * Popper.js uses a set of 7 modifiers to provide all the basic functionalities
+ * needed by the library.
+ *
+ * Each modifier is an object containing several properties listed below.
+ * @namespace Modifiers
+ * @param {Object} modifier - Modifier descriptor
+ * @param {Integer} modifier.order
+ *      The `order` property defines the execution order of the modifiers.
+ *      The built-in modifiers have orders with a gap of 100 units in between,
+ *      this allows you to inject additional modifiers between the existing ones
+ *      without having to redefine the order of all of them.
+ *      The modifiers are executed starting from the one with the lowest order.
+ * @param {Boolean} modifier.enabled - When `true`, the modifier will be used.
+ * @param {Modifiers~modifier} modifier.function - Modifier function.
+ * @param {Modifiers~onLoad} modifier.onLoad - Function executed on popper initalization
+ * @return {Object} data - Each modifier must return the modified `data` object.
+ */
+var modifiers = {
+  shift: {
+    order: 100,
+    enabled: true,
+    function: shift
+  },
+  offset: {
+    order: 200,
+    enabled: true,
+    function: offset,
+    // nudges popper from its origin by the given amount of pixels (can be negative)
+    offset: 0
+  },
+  preventOverflow: {
+    order: 300,
+    enabled: true,
+    function: preventOverflow,
+    // popper will try to prevent overflow following these priorities
+    //  by default, then, it could overflow on the left and on top of the boundariesElement
+    priority: ['left', 'right', 'top', 'bottom'],
+    // amount of pixel used to define a minimum distance between the boundaries and the popper
+    // this makes sure the popper has always a little padding between the edges of its container
+    padding: 5,
+    boundariesElement: 'scrollParent'
+  },
+  keepTogether: {
+    order: 400,
+    enabled: true,
+    function: keepTogether
+  },
+  arrow: {
+    order: 500,
+    enabled: true,
+    function: arrow,
+    // selector or node used as arrow
+    element: '[x-arrow]'
+  },
+  flip: {
+    order: 600,
+    enabled: true,
+    function: flip,
+    // the behavior used to change the popper's placement
+    behavior: 'flip',
+    // the popper will flip if it hits the edges of the boundariesElement - padding
+    padding: 5,
+    boundariesElement: 'viewport'
+  },
+  inner: {
+    order: 700,
+    enabled: false,
+    function: inner
+  },
+  hide: {
+    order: 800,
+    enabled: true,
+    function: hide
+  },
+  applyStyle: {
+    order: 900,
+    enabled: true,
+    // if true, it uses the CSS 3d transformation to position the popper
+    gpuAcceleration: true,
+    function: applyStyle,
+    onLoad: applyStyleOnLoad
+  }
+};
+
+/**
+ * Modifiers can edit the `data` object to change the beheavior of the popper.
+ * This object contains all the informations used by Popper.js to compute the
+ * popper position.
+ * The modifier can edit the data as needed, and then `return` it as result.
+ *
+ * @callback Modifiers~modifier
+ * @param {dataObject} data
+ * @return {dataObject} modified data
+ */
+
+/**
+ * The `dataObject` is an object containing all the informations used by Popper.js
+ * this object get passed to modifiers and to the `onCreate` and `onUpdate` callbacks.
+ * @name dataObject
+ * @property {Object} data.instance The Popper.js instance
+ * @property {String} data.placement Placement applied to popper
+ * @property {String} data.originalPlacement Placement originally defined on init
+ * @property {Boolean} data.flipped True if popper has been flipped by flip modifier
+ * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper.
+ * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier
+ * @property {Object} data.styles Any CSS property defined here will be applied to the popper, it expects the JavaScript nomenclature (eg. `marginBottom`)
+ * @property {Object} data.boundaries Offsets of the popper boundaries
+ * @property {Object} data.offsets The measurements of popper, reference and arrow elements.
+ * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values
+ * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values
+ * @property {Object} data.offsets.arro] `top` and `left` offsets, only one of them will be different from 0
+ */
+
+// Utils
+// Modifiers
+// default options
+var DEFAULTS = {
+    // placement of the popper
+    placement: 'bottom',
+
+    // whether events (resize, scroll) are initially enabled
+    eventsEnabled: true,
+
+    /**
+     * Callback called when the popper is created.
+     * By default, is set to no-op.
+     * Access Popper.js instance with `data.instance`.
+     * @callback createCallback
+     * @static
+     * @param {dataObject} data
+     */
+    onCreate: function onCreate() {},
+
+    /**
+     * Callback called when the popper is updated, this callback is not called
+     * on the initialization/creation of the popper, but only on subsequent
+     * updates.
+     * By default, is set to no-op.
+     * Access Popper.js instance with `data.instance`.
+     * @callback updateCallback
+     * @static
+     * @param {dataObject} data
+     */
+    onUpdate: function onUpdate() {},
+
+    // list of functions used to modify the offsets before they are applied to the popper
+    modifiers: modifiers
+};
+
+/**
+ * Create a new Popper.js instance
+ * @class Popper
+ * @param {HTMLElement} reference - The reference element used to position the popper
+ * @param {HTMLElement} popper - The HTML element used as popper.
+ * @param {Object} options
+ * @param {String} options.placement=bottom
+ *      Placement of the popper accepted values: `top(-start, -end), right(-start, -end), bottom(-start, -end),
+ *      left(-start, -end)`
+ *
+ * @param {Boolean} options.eventsEnabled=true
+ *      Whether events (resize, scroll) are initially enabled
+ * @param {Boolean} options.gpuAcceleration=true
+ *      When this property is set to true, the popper position will be applied using CSS3 translate3d, allowing the
+ *      browser to use the GPU to accelerate the rendering.
+ *      If set to false, the popper will be placed using `top` and `left` properties, not using the GPU.
+ *
+ * @param {Boolean} options.removeOnDestroy=false
+ *      Set to true if you want to automatically remove the popper when you call the `destroy` method.
+ *
+ * @param {Object} options.modifiers
+ *      List of functions used to modify the data before they are applied to the popper (see source code for default values)
+ *
+ * @param {Object} options.modifiers.arrow - Arrow modifier configuration
+ * @param {String|HTMLElement} options.modifiers.arrow.element='[x-arrow]'
+ *      The DOM Node used as arrow for the popper, or a CSS selector used to get the DOM node. It must be child of
+ *      its parent Popper. Popper.js will apply to the given element the style required to align the arrow with its
+ *      reference element.
+ *      By default, it will look for a child node of the popper with the `x-arrow` attribute.
+ *
+ * @param {Object} options.modifiers.offset - Offset modifier configuration
+ * @param {Number} options.modifiers.offset.offset=0
+ *      Amount of pixels the popper will be shifted (can be negative).
+ *
+ * @param {Object} options.modifiers.preventOverflow - PreventOverflow modifier configuration
+ * @param {Array} [options.modifiers.preventOverflow.priority=['left', 'right', 'top', 'bottom']]
+ *      Priority used when Popper.js tries to avoid overflows from the boundaries, they will be checked in order,
+ *      this means that the last one will never overflow
+ * @param {String|HTMLElement} options.modifiers.preventOverflow.boundariesElement='scrollParent'
+ *      Boundaries used by the modifier, can be `scrollParent`, `window`, `viewport` or any DOM element.
+ * @param {Number} options.modifiers.preventOverflow.padding=5
+ *      Amount of pixel used to define a minimum distance between the boundaries and the popper
+ *      this makes sure the popper has always a little padding between the edges of its container.
+ *
+ * @param {Object} options.modifiers.flip - Flip modifier configuration
+ * @param {String|Array} options.modifiers.flip.behavior='flip'
+ *      The behavior used by the `flip` modifier to change the placement of the popper when the latter is trying to
+ *      overlap its reference element. Defining `flip` as value, the placement will be flipped on
+ *      its axis (`right - left`, `top - bottom`).
+ *      You can even pass an array of placements (eg: `['right', 'left', 'top']` ) to manually specify
+ *      how alter the placement when a flip is needed. (eg. in the above example, it would first flip from right to left,
+ *      then, if even in its new placement, the popper is overlapping its reference element, it will be moved to top)
+ * @param {String|HTMLElement} options.modifiers.flip.boundariesElement='viewport'
+ *      The element which will define the boundaries of the popper position, the popper will never be placed outside
+ *      of the defined boundaries (except if `keepTogether` is enabled)
+ *
+ * @param {Object} options.modifiers.inner - Inner modifier configuration
+ * @param {Number} options.modifiers.inner.enabled=false
+ *      Set to `true` to make the popper flow toward the inner of the reference element.
+ *
+ * @param {Number} options.modifiers.flip.padding=5
+ *      Amount of pixel used to define a minimum distance between the boundaries and the popper
+ *      this makes sure the popper has always a little padding between the edges of its container.
+ *
+ * @param {createCallback} options.onCreate - onCreate callback
+ *      Function called after the Popper has been instantiated.
+ *
+ * @param {updateCallback} options.onUpdate - onUpdate callback
+ *      Function called on subsequent updates of Popper.
+ *
+ * @return {Object} instance - The generated Popper.js instance
+ */
+
+var Popper = function () {
+    function Popper(reference, popper) {
+        var _this = this;
+
+        var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+        classCallCheck(this, Popper);
+
+        this.scheduleUpdate = function () {
+            return requestAnimationFrame(_this.update);
+        };
+
+        // make update() debounced, so that it only runs at most once-per-tick
+        this.update = debounce(this.update.bind(this));
+
+        // with {} we create a new object with the options inside it
+        this.options = _extends({}, Popper.Defaults, options);
+
+        // init state
+        this.state = {
+            isDestroyed: false,
+            isCreated: false,
+            scrollParents: []
+        };
+
+        // get reference and popper elements (allow jQuery wrappers)
+        this.reference = reference.jquery ? reference[0] : reference;
+        this.popper = popper.jquery ? popper[0] : popper;
+
+        // refactoring modifiers' list (Object => Array)
+        this.modifiers = Object.keys(Popper.Defaults.modifiers).map(function (name) {
+            return _extends({ name: name }, Popper.Defaults.modifiers[name]);
+        });
+
+        // assign default values to modifiers, making sure to override them with
+        // the ones defined by user
+        this.modifiers = this.modifiers.map(function (defaultConfig) {
+            var userConfig = options.modifiers && options.modifiers[defaultConfig.name] || {};
+            return _extends({}, defaultConfig, userConfig);
+        });
+
+        // add custom modifiers to the modifiers list
+        if (options.modifiers) {
+            this.options.modifiers = _extends({}, Popper.Defaults.modifiers, options.modifiers);
+            Object.keys(options.modifiers).forEach(function (name) {
+                // take in account only custom modifiers
+                if (Popper.Defaults.modifiers[name] === undefined) {
+                    var modifier = options.modifiers[name];
+                    modifier.name = name;
+                    _this.modifiers.push(modifier);
+                }
+            });
+        }
+
+        // get the popper position type
+        this.state.position = getPosition(this.reference);
+
+        // sort the modifiers by order
+        this.modifiers = this.modifiers.sort(function (a, b) {
+            return a.order - b.order;
+        });
+
+        // modifiers have the ability to execute arbitrary code when Popper.js get inited
+        // such code is executed in the same order of its modifier
+        // they could add new properties to their options configuration
+        // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!
+        this.modifiers.forEach(function (modifierOptions) {
+            if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {
+                modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);
+            }
+        });
+
+        // determine how we should set the origin of offsets
+        this.state.isParentTransformed = isTransformed(this.popper.parentNode);
+
+        // fire the first update to position the popper in the right place
+        this.update();
+
+        var eventsEnabled = this.options.eventsEnabled;
+        if (eventsEnabled) {
+            // setup event listeners, they will take care of update the position in specific situations
+            this.enableEventListeners();
+        }
+
+        this.state.eventsEnabled = eventsEnabled;
+    }
 
-      //
-      // Methods
-      //
-
-      /**
-       * Updates the position of the popper, computing the new offsets and applying the new style
-       * @method
-       * @param {Boolean} isFirstCall
-       *      When true, the onCreate callback is called, otherwise it calls the onUpdate callback
-       * @memberof Popper
-       */
-
-
-      createClass(Popper, [{
-          key: 'update',
-          value: function update(isFirstCall) {
-              var _this2 = this;
-
-              var data = { instance: this, styles: {} };
-
-              // make sure to apply the popper position before any computation
-              this.state.position = getPosition(this.popper, this.reference);
-              setStyle(this.popper, { position: this.state.position });
-
-              // to avoid useless computations we throttle the popper position refresh to 60fps
-              window.requestAnimationFrame(function () {
-                  // if popper is destroyed, don't perform any further update
-                  if (_this2.state.isDestroyed) {
-                      return;
-                  }
-
-                  var now = window.performance.now();
-                  if (now - _this2.state.lastFrame <= 16) {
-                      // this update fired to early! drop it
-                      // but schedule a new one that will be ran at the end of the updates
-                      // chain to make sure everything is proper updated
-                      return _this2.update();
-                  }
-                  _this2.state.lastFrame = now;
-
-                  // store placement inside the data object, modifiers will be able to edit `placement` if needed
-                  // and refer to originalPlacement to know the original value
-                  data.placement = _this2.options.placement;
-                  data.originalPlacement = _this2.options.placement;
-
-                  // compute the popper and reference offsets and put them inside data.offsets
-                  data.offsets = getOffsets(_this2.state, _this2.popper, _this2.reference, data.placement);
-
-                  // get boundaries
-                  data.boundaries = getBoundaries(_this2.popper, data, _this2.options.boundariesPadding, _this2.options.boundariesElement);
-
-                  // run the modifiers
-                  data = runModifiers(_this2.modifiers, _this2.options, data);
-
-                  // the first `update` will call `onCreate` callback
-                  // the other ones will call `onUpdate` callback
-                  if (isFirstCall && isFunction(_this2.state.createCalback)) {
-                      _this2.state.createCalback(data);
-                  } else if (!isFirstCall && isFunction(_this2.state.updateCallback)) {
-                      _this2.state.updateCallback(data);
-                  }
-              });
-          }
-
-          /**
-           * If a function is passed, it will be executed after the initialization of popper with as first argument the Popper instance.
-           * @method
-           * @memberof Popper
-           * @param {createCallback} callback
-           */
-
-      }, {
-          key: 'onCreate',
-          value: function onCreate(callback) {
-              // the createCallbacks return as first argument the popper instance
-              this.state.createCalback = callback;
-              return this;
-          }
-
-          /**
-           * Callback called when the popper is created.
-           * Access Popper.js instance with `data.instance`.
-           * @callback createCallback
-           * @static
-           * @param {dataObject} data
-           */
-
-          /**
-           * If a function is passed, it will be executed after each update of popper with as first argument the set of coordinates and informations
-           * used to style popper and its arrow.
-           * NOTE: it doesn't get fired on the first call of the `Popper.update()` method inside the `Popper` constructor!
-           * @method
-           * @memberof Popper
-           * @param {updateCallback} callback
-           */
-
-      }, {
-          key: 'onUpdate',
-          value: function onUpdate(callback) {
-              this.state.updateCallback = callback;
-              return this;
-          }
-
-          /**
-           * Callback called when the popper is updated, this callback is not called
-           * on the initialization/creation of the popper, but only on subsequent
-           * updates.
-           * Access Popper.js instance with `data.instance`.
-           * @callback updateCallback
-           * @static
-           * @param {dataObject} data
-           */
-
-          /**
-           * Destroy the popper
-           * @method
-           * @memberof Popper
-           */
-
-      }, {
-          key: 'destroy',
-          value: function destroy() {
-              this.state.isDestroyed = true;
-              this.popper.removeAttribute('x-placement');
-              this.popper.style.left = '';
-              this.popper.style.position = '';
-              this.popper.style.top = '';
-              this.popper.style[getSupportedPropertyName('transform')] = '';
-              this.state = removeEventListeners(this.reference, this.state, this.options);
-
-              // remove the popper if user explicity asked for the deletion on destroy
-              // do not use `remove` because IE11 doesn't support it
-              if (this.options.removeOnDestroy) {
-                  this.popper.parentNode.removeChild(this.popper);
-              }
-              return this;
-          }
-
-          /**
-           * Collection of utilities useful when writing custom modifiers
-           * @memberof Popper
-           */
-
-
-          /**
-           * Default Popper.js options
-           * @memberof Popper
-           */
-
-      }]);
-      return Popper;
-  }();
-
-  Popper.Utils = Utils;
-
-  return Popper;
-
-}));
\ No newline at end of file
+    //
+    // Methods
+    //
+
+    /**
+     * Updates the position of the popper, computing the new offsets and applying the new style
+     * Prefer `scheduleUpdate` over `update` because of performance reasons
+     * @method
+     * @memberof Popper
+     */
+
+
+    createClass(Popper, [{
+        key: 'update',
+        value: function update() {
+            // if popper is destroyed, don't perform any further update
+            if (this.state.isDestroyed) {
+                return;
+            }
+
+            var data = {
+                instance: this,
+                styles: {},
+                attributes: {},
+                flipped: false,
+                offsets: {}
+            };
+
+            // make sure to apply the popper position before any computation
+            this.state.position = getPosition(this.reference);
+            setStyles(this.popper, { position: this.state.position });
+
+            // compute reference element offsets
+            data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference);
+
+            // compute auto placement, store placement inside the data object,
+            // modifiers will be able to edit `placement` if needed
+            // and refer to originalPlacement to know the original value
+            data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper);
+
+            // store the computed placement inside `originalPlacement`
+            data.originalPlacement = this.options.placement;
+
+            // compute the popper offsets
+            data.offsets.popper = getPopperOffsets(this.state, this.popper, data.offsets.reference, data.placement);
+
+            // run the modifiers
+            data = runModifiers(this.modifiers, data);
+
+            // the first `update` will call `onCreate` callback
+            // the other ones will call `onUpdate` callback
+            if (!this.state.isCreated) {
+                this.state.isCreated = true;
+                this.options.onCreate(data);
+            } else {
+                this.options.onUpdate(data);
+            }
+        }
+
+        /**
+         * Schedule an update, it will run on the next UI update available
+         * @method scheduleUpdate
+         * @memberof Popper
+         */
+
+    }, {
+        key: 'destroy',
+
+
+        /**
+         * Destroy the popper
+         * @method
+         * @memberof Popper
+         */
+        value: function destroy() {
+            this.state.isDestroyed = true;
+
+            // touch DOM only if `applyStyle` modifier is enabled
+            if (isModifierEnabled(this.modifiers, 'applyStyle')) {
+                this.popper.removeAttribute('x-placement');
+                this.popper.style.left = '';
+                this.popper.style.position = '';
+                this.popper.style.top = '';
+                this.popper.style[getSupportedPropertyName('transform')] = '';
+            }
+
+            this.disableEventListeners();
+
+            // remove the popper if user explicity asked for the deletion on destroy
+            // do not use `remove` because IE11 doesn't support it
+            if (this.options.removeOnDestroy) {
+                this.popper.parentNode.removeChild(this.popper);
+            }
+            return this;
+        }
+
+        /**
+         * it will add resize/scroll events and start recalculating
+         * position of the popper element when they are triggered
+         * @method
+         * @memberof Popper
+         */
+
+    }, {
+        key: 'enableEventListeners',
+        value: function enableEventListeners() {
+            if (!this.state.eventsEnabled) {
+                this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);
+            }
+        }
+
+        /**
+         * it will remove resize/scroll events and won't recalculate
+         * popper position when they are triggered. It also won't trigger onUpdate callback anymore,
+         * unless you call 'update' method manually.
+         * @method
+         * @memberof Popper
+         */
+
+    }, {
+        key: 'disableEventListeners',
+        value: function disableEventListeners() {
+            if (this.state.eventsEnabled) {
+                window.cancelAnimationFrame(this.scheduleUpdate);
+                this.state = removeEventListeners(this.reference, this.state);
+            }
+        }
+
+        /**
+         * Collection of utilities useful when writing custom modifiers
+         * @memberof Popper
+         */
+
+
+        /**
+         * List of accepted placements to use as values of the `placement` option
+         * @memberof Popper
+         */
+
+
+        /**
+         * Default Popper.js options
+         * @memberof Popper
+         */
+
+    }]);
+    return Popper;
+}();
+
+Popper.Utils = Utils;
+Popper.placements = ['auto', 'auto-start', 'auto-end', 'top', 'top-start', 'top-end', 'right', 'right-start', 'right-end', 'bottom', 'bottom-start', 'bottom-end', 'left', 'left-start', 'left-end'];
+Popper.Defaults = DEFAULTS;
+
+return Popper;
+
+})));
+//# sourceMappingURL=popper.es5.js.map
index d09a505..ff3a01c 100644 (file)
@@ -5,13 +5,13 @@
     define(["jquery","./popper"], function (a0,b1) {
       return (root['Tour'] = factory(a0,b1));
     });
-  } else if (typeof exports === 'object') {
+  } else if (typeof module === 'object' && module.exports) {
     // Node. Does not work with strict CommonJS, but
     // only CommonJS-like environments that support module.exports,
     // like Node.
     module.exports = factory(require("jquery"),require("popper.js"));
   } else {
-    root['Tour'] = factory($,Popper);
+    root['Tour'] = factory(root["$"],root["Popper"]);
   }
 }(this, function ($, Popper) {
 
@@ -24,7 +24,7 @@
  * @param   {object}    config  The configuration object.
  */
 
-var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
 
 function Tour(config) {
     this.init(config);
@@ -773,12 +773,8 @@ Tour.prototype.addStepToPage = function (stepConfig) {
         // Add the backdrop.
         this.positionBackdrop(stepConfig);
 
-        if (stepConfig.attachPoint === 'append') {
-            stepConfig.attachTo.append(currentStepNode);
-            this.currentStepNode = currentStepNode;
-        } else {
-            this.currentStepNode = currentStepNode.insertAfter(stepConfig.attachTo);
-        }
+        $(document.body).append(currentStepNode);
+        this.currentStepNode = currentStepNode;
 
         // Ensure that the step node is positioned.
         // Some situations mean that the value is not properly calculated without this step.
@@ -807,7 +803,7 @@ Tour.prototype.addStepToPage = function (stepConfig) {
         currentStepNode.addClass('orphan');
 
         // It lives in the body.
-        stepConfig.attachTo.append(currentStepNode);
+        $(document.body).append(currentStepNode);
         this.currentStepNode = currentStepNode;
 
         this.currentStepNode.offset(this.calculateStepPositionInPage());
@@ -1231,11 +1227,6 @@ Tour.prototype.positionStep = function (stepConfig) {
         }
     };
 
-    var boundaryElement = target.closest('section');
-    if (boundaryElement.length) {
-        config.boundariesElement = boundaryElement[0];
-    }
-
     var background = $('[data-flexitour="step-background"]');
     if (background.length) {
         target = background;
@@ -1311,6 +1302,8 @@ Tour.prototype.positionBackdrop = function (stepConfig) {
             var targetPosition = this.calculatePosition(targetNode);
             if (targetPosition === 'fixed') {
                 background.css('top', 0);
+            } else if (targetPosition === 'absolute') {
+                background.css('position', 'fixed');
             }
 
             var fader = background.clone();
index 0d845ab..7d9c340 100644 (file)
@@ -4,14 +4,14 @@
     <location>amd/src/tour.js</location>
     <name>Flexitour</name>
     <license>GPLv3</license>
-    <version>0.9.10</version>
+    <version>0.10.0</version>
     <licenseversion>3</licenseversion>
   </library>
   <library>
     <location>amd/src/popper.js</location>
     <name>Popper.js</name>
     <license>MIT</license>
-    <version>v1.0.0-alpha.3</version>
+    <version>v1.0.8</version>
     <licenseversion></licenseversion>
   </library>
 </libraries>
index 421171a..fcb42b7 100644 (file)
@@ -103,12 +103,7 @@ class login implements renderable, templatable {
         }
 
         // Identity providers.
-        $identityproviders = [];
-        foreach ($authsequence as $authname) {
-            $authplugin = get_auth_plugin($authname);
-            $identityproviders = array_merge($identityproviders, $authplugin->loginpage_idp_list($SESSION->wantsurl));
-        }
-        $this->identityproviders = $identityproviders;
+        $this->identityproviders = \auth_plugin_base::get_identity_providers($authsequence);
     }
 
     /**
@@ -121,21 +116,8 @@ class login implements renderable, templatable {
     }
 
     public function export_for_template(renderer_base $output) {
-        global $CFG;
-
-        $identityproviders = array_map(function($idp) use ($output) {
-
-            if (!empty($idp['icon'])) {
-                $idp['iconurl'] = $output->pix_url($idp['icon']->key, $idp['icon']->component);
-            } else if ($idp['iconurl'] instanceof moodle_url) {
-                $idp['iconurl'] = $idp['iconurl']->out(false);
-            }
-            unset($idp['icon']);
-            if ($idp['url'] instanceof moodle_url) {
-                $idp['url'] = $idp['url']->out(false);
-            }
-            return $idp;
-        }, $this->identityproviders);
+
+        $identityproviders = \auth_plugin_base::prepare_identity_providers_for_output($this->identityproviders, $output);
 
         $data = new stdClass();
         $data->autofocusform = $this->autofocusform;
index 6710afd..6e8382a 100644 (file)
@@ -1379,7 +1379,7 @@ class moodle1_file_manager implements loggable {
     protected function make_file_record(array $fileinfo) {
 
         $defaultrecord = array(
-            'contenthash'   => 'da39a3ee5e6b4b0d3255bfef95601890afd80709',  // sha1 of an empty file
+            'contenthash'   => file_storage::hash_from_string(''),
             'contextid'     => $this->contextid,
             'component'     => $this->component,
             'filearea'      => $this->filearea,
@@ -1422,7 +1422,7 @@ class moodle1_file_manager implements loggable {
             throw new moodle1_convert_exception('file_not_readable');
         }
 
-        $contenthash = sha1_file($pathname);
+        $contenthash = file_storage::hash_from_path($pathname);
         $filesize    = filesize($pathname);
         $hashpath    = $this->converter->get_workdir_path().'/files/'.substr($contenthash, 0, 2);
         $hashfile    = "$hashpath/$contenthash";
index 88681b8..6502ef3 100644 (file)
@@ -64,7 +64,7 @@ class core_backup_moodle1_converter_testcase extends advanced_testcase {
             "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif",
             "$CFG->tempdir/backup/$this->tempdir/moddata/unittest/4/icon.gif"
         );
-        $this->iconhash = sha1_file($CFG->tempdir.'/backup/'.$this->tempdir.'/moddata/unittest/4/icon.gif');
+        $this->iconhash = file_storage::hash_from_path($CFG->tempdir.'/backup/'.$this->tempdir.'/moddata/unittest/4/icon.gif');
         copy(
             "$CFG->dirroot/backup/converter/moodle1/tests/fixtures/icon.gif",
             "$CFG->tempdir/backup/$this->tempdir/moddata/unittest/4/7/icon.gif"
@@ -351,8 +351,8 @@ class core_backup_moodle1_converter_testcase extends advanced_testcase {
         $this->assertEquals('array', gettype($files['/file1.gif']));
         $this->assertEquals('array', gettype($files['/sub1/.']));
         $this->assertEquals('array', gettype($files['/sub1/file2.gif']));
-        $this->assertEquals(sha1(''), $files['/.']['contenthash']);
-        $this->assertEquals(sha1(''), $files['/sub1/.']['contenthash']);
+        $this->assertEquals(file_storage::hash_from_string(''), $files['/.']['contenthash']);
+        $this->assertEquals(file_storage::hash_from_string(''), $files['/sub1/.']['contenthash']);
         $this->assertEquals($this->iconhash, $files['/file1.gif']['contenthash']);
         $this->assertEquals($this->iconhash, $files['/sub1/file2.gif']['contenthash']);
 
index 8da4f1e..ad9bc00 100644 (file)
@@ -44,6 +44,10 @@ class cachestore_redis_addinstance_form extends cachestore_addinstance_form {
         $form->addHelpButton('server', 'server', 'cachestore_redis');
         $form->addRule('server', get_string('required'), 'required');
 
+        $form->addElement('passwordunmask', 'password', get_string('password', 'cachestore_redis'));
+        $form->setType('password', PARAM_RAW);
+        $form->addHelpButton('password', 'password', 'cachestore_redis');
+
         $form->addElement('text', 'prefix', get_string('prefix', 'cachestore_redis'), array('size' => 16));
         $form->setType('prefix', PARAM_TEXT); // We set to text but we have a rule to limit to alphanumext.
         $form->addHelpButton('prefix', 'prefix', 'cachestore_redis');
@@ -55,4 +59,4 @@ class cachestore_redis_addinstance_form extends cachestore_addinstance_form {
         $form->setDefault('serializer', Redis::SERIALIZER_PHP);
         $form->setType('serializer', PARAM_INT);
     }
-}
\ No newline at end of file
+}
index a44a156..26aad4e 100644 (file)
@@ -34,8 +34,12 @@ $string['serializer_igbinary'] = 'The igbinary serializer.';
 $string['serializer_php'] = 'The default PHP serializer.';
 $string['server'] = 'Server';
 $string['server_help'] = 'This sets the hostname or IP address of the Redis server to use.';
+$string['password'] = 'Password';
+$string['password_help'] = 'This sets the password of the Redis server.';
 $string['test_server'] = 'Test server';
 $string['test_server_desc'] = 'Redis server to use for testing.';
+$string['test_password'] = 'Test server password';
+$string['test_password_desc'] = 'Redis test server password.';
 $string['test_serializer'] = 'Serializer';
 $string['test_serializer_desc'] = 'Serializer to use for testing.';
 $string['useserializer'] = 'Use serializer';
index fd19709..bcf56fd 100644 (file)
@@ -134,8 +134,9 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_
         if (array_key_exists('serializer', $configuration)) {
             $this->serializer = (int)$configuration['serializer'];
         }
+        $password = !empty($configuration['password']) ? $configuration['password'] : '';
         $prefix = !empty($configuration['prefix']) ? $configuration['prefix'] : '';
-        $this->redis = $this->new_redis($configuration['server'], $prefix);
+        $this->redis = $this->new_redis($configuration['server'], $prefix, $password);
     }
 
     /**
@@ -144,9 +145,10 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_
      *
      * @param string $server The server connection string
      * @param string $prefix The key prefix
+     * @param string $password The server connection password
      * @return Redis
      */
-    protected function new_redis($server, $prefix = '') {
+    protected function new_redis($server, $prefix = '', $password = '') {
         $redis = new Redis();
         $port = null;
         if (strpos($server, ':')) {
@@ -155,6 +157,9 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_
             $port = $serverconf[1];
         }
         if ($redis->connect($server, $port)) {
+            if (!empty($password)) {
+                $redis->auth($password);
+            }
             $redis->setOption(Redis::OPT_SERIALIZER, $this->serializer);
             if (!empty($prefix)) {
                 $redis->setOption(Redis::OPT_PREFIX, $prefix);
@@ -439,6 +444,7 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_
         return array(
             'server' => $data->server,
             'prefix' => $data->prefix,
+            'password' => $data->password,
             'serializer' => $data->serializer
         );
     }
@@ -454,6 +460,7 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_
         $data = array();
         $data['server'] = $config['server'];
         $data['prefix'] = !empty($config['prefix']) ? $config['prefix'] : '';
+        $data['password'] = !empty($config['password']) ? $config['password'] : '';
         if (!empty($config['serializer'])) {
             $data['serializer'] = $config['serializer'];
         }
@@ -479,6 +486,9 @@ class cachestore_redis extends cache_store implements cache_is_key_aware, cache_
         if (!empty($config->test_serializer)) {
             $configuration['serializer'] = $config->test_serializer;
         }
+        if (!empty($config->test_password)) {
+            $configuration['password'] = $config->test_password;
+        }
         $cache = new cachestore_redis('Redis test', $configuration);
         $cache->initialise($definition);
 
index 0787815..67f651c 100644 (file)
@@ -34,6 +34,14 @@ $settings->add(
         16
     )
 );
+$settings->add(
+    new admin_setting_configpasswordunmask(
+        'cachestore_redis/test_password',
+        get_string('test_password', 'cachestore_redis'),
+        get_string('test_password_desc', 'cachestore_redis'),
+        ''
+    )
+);
 
 if (class_exists('Redis')) { // Only if Redis is available.
 
index 432a85a..3a8afba 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version    = 2016120500;
+$plugin->version    = 2017031900;
 $plugin->requires   = 2016112900; // Requires this Moodle version (3.0.4).
 $plugin->maturity   = MATURITY_STABLE;
 $plugin->component  = 'cachestore_redis';
index 41fd950..a6882a0 100644 (file)
@@ -265,6 +265,7 @@ $CFG->admin = 'admin';
 //      $CFG->session_redis_host = '127.0.0.1';
 //      $CFG->session_redis_port = 6379;  // Optional.
 //      $CFG->session_redis_database = 0;  // Optional, default is db 0.
+//      $CFG->session_redis_auth = ''; // Optional, default is don't set one.
 //      $CFG->session_redis_prefix = ''; // Optional, default is don't set one.
 //      $CFG->session_redis_acquire_lock_timeout = 120;
 //      $CFG->session_redis_lock_expire = 7200;
index 5d9a7d1..6efb9f4 100644 (file)
@@ -441,7 +441,9 @@ class core_course_external extends external_api {
                 $exceptionparam->courseid = $course->id;
                 throw new moodle_exception('errorcoursecontextnotvalid', 'webservice', '', $exceptionparam);
             }
-            require_capability('moodle/course:view', $context);
+            if ($course->id != SITEID) {
+                require_capability('moodle/course:view', $context);
+            }
 
             $courseinfo = array();
             $courseinfo['id'] = $course->id;
index 34da257..b30e442 100644 (file)
@@ -642,6 +642,32 @@ class core_course_externallib_testcase extends externallib_advanced_testcase {
         $this->assertEquals($DB->count_records('course'), count($courses));
     }
 
+    /**
+     * Test get_courses without capability
+     */
+    public function test_get_courses_without_capability() {
+        $this->resetAfterTest(true);
+
+        $course1 = $this->getDataGenerator()->create_course();
+        $this->setUser($this->getDataGenerator()->create_user());
+
+        // No permissions are required to get the site course.
+        $courses = core_course_external::get_courses(array('ids' => [SITEID]));
+        $courses = external_api::clean_returnvalue(core_course_external::get_courses_returns(), $courses);
+
+        $this->assertEquals(1, count($courses));
+        $this->assertEquals('PHPUnit test site', $courses[0]['fullname']);
+        $this->assertEquals('site', $courses[0]['format']);
+
+        // Requesting course without being enrolled or capability to view it will throw an exception.
+        try {
+            core_course_external::get_courses(array('ids' => [$course1->id]));
+            $this->fail('Exception expected');
+        } catch (moodle_exception $e) {
+            $this->assertEquals(1, preg_match('/Course or activity not accessible. \(Not enrolled\)/', $e->getMessage()));
+        }
+    }
+
     /**
      * Test search_courses
      */
index 7923908..32793d3 100644 (file)
@@ -118,8 +118,8 @@ class converter {
                 // Unable to fetch the converter instance.
                 // Reset the status back to PENDING so that it may be picked up again.
                 $conversion->set('status', conversion::STATUS_PENDING);
-                $conversion->update();
             }
+            $conversion->update();
         }
 
         // Refresh the status.
@@ -134,6 +134,7 @@ class converter {
             if (!$currentconverter) {
                 // No more converters available.
                 $conversion->set('status', conversion::STATUS_FAILED);
+                $conversion->update();
                 return $this;
             }
 
index a8679e2..bbcedf0 100644 (file)
@@ -105,10 +105,6 @@ class converter implements \core_files\converter_interface {
             return $this;
         }
 
-        // Update the status to IN_PROGRESS.
-        $conversion->set('status', \core_files\conversion::STATUS_IN_PROGRESS);
-        $conversion->update();
-
         // Copy the file to the tmp dir.
         $uniqdir = make_unique_writable_directory(make_temp_directory('core_file/conversions'));
         \core_shutdown_manager::register_function('remove_dir', array($uniqdir));
index 6f182c6..950d593 100644 (file)
@@ -417,6 +417,7 @@ class core_files_converter_testcase extends advanced_testcase {
         $conversion->set_sourcefile($file);
         $conversion->set('targetformat', 'target');
         $conversion->set('status', conversion::STATUS_IN_PROGRESS);
+        $conversion->create();
 
         $converterinstance = $this->get_mocked_converter([
                 'poll_conversion_status',
@@ -484,6 +485,7 @@ class core_files_converter_testcase extends advanced_testcase {
             'sourcefileid' => $file->get_id(),
             'targetformat' => 'target',
         ]);
+        $conversion->create();
 
         $converter->poll_conversion($conversion);
 
diff --git a/filter/mathjaxloader/contrib/a11y/accessibility-menu.js b/filter/mathjaxloader/contrib/a11y/accessibility-menu.js
new file mode 100644 (file)
index 0000000..3f25db5
--- /dev/null
@@ -0,0 +1 @@
+!function(a,b){var c,d,e=a.config.menuSettings,f=Function.prototype.bind?function(a,b){return a.bind(b)}:function(a,b){return function(){a.apply(b,arguments)}},g=Object.keys||function(a){var b=[];for(var c in a)a.hasOwnProperty(c)&&b.push(c);return b},h=MathJax.Ajax.config.path;h.a11y||(h.a11y=h.Contrib?h.Contrib+"/a11y":(String(location.protocol).match(/^https?:/)?"":"http:")+"//cdn.mathjax.org/mathjax/contrib/a11y");var i=b["accessibility-menu"]={version:"1.1",prefix:"",default:{},modules:[],MakeOption:function(a){return i.prefix+a},GetOption:function(a){return e[i.MakeOption(a)]},AddDefaults:function(){for(var a,b=g(i.default),c=0;a=b[c];c++){var d=i.MakeOption(a);"undefined"==typeof e[d]&&(e[d]=i.default[a])}},AddMenu:function(){for(var a,b=Array(this.modules.length),e=0;a=this.modules[e];e++)b[e]=a.placeHolder;var f=d.FindId("Accessibility");if(f)b.unshift(c.RULE()),f.submenu.items.push.apply(f.submenu.items,b);else{var g=(d.FindId("Settings","Renderer")||{}).submenu;g&&(b.unshift(c.RULE()),b.unshift(g.items.pop()),b.unshift(g.items.pop())),b.unshift("Accessibility");var f=c.SUBMENU.apply(c.SUBMENU,b),h=d.IndexOfId("Locale");h?d.items.splice(h,0,f):d.items.push(c.RULE(),f)}},Register:function(a){i.default[a.option]=!1,i.modules.push(a)},Startup:function(){c=MathJax.Menu.ITEM,d=MathJax.Menu.menu;for(var a,b=0;a=this.modules[b];b++)a.CreateMenu();this.AddMenu()},LoadExtensions:function(){for(var b=[],c=0;module=this.modules[c];c++)e[module.option]&&b.push(module.module);return b.length?a.Startup.loadArray(b):null}},j=MathJax.Extension.ModuleLoader=MathJax.Object.Subclass({option:"",name:["",""],module:"",placeHolder:null,submenu:!1,extension:null,Init:function(a,b,c,d,e){this.option=a,this.name=[b.replace(/ /g,""),b],this.module=c,this.extension=d,this.submenu=e||!1},CreateMenu:function(){var a=f(this.Load,this);this.submenu?this.placeHolder=c.SUBMENU(this.name,c.CHECKBOX(["Activate","Activate"],i.MakeOption(this.option),{action:a}),c.RULE(),c.COMMAND(["OptionsWhenActive","(Options when Active)"],null,{disabled:!0})):this.placeHolder=c.CHECKBOX(this.name,i.MakeOption(this.option),{action:a})},Load:function(){a.Queue(["Require",MathJax.Ajax,this.module,["Enable",this]])},Enable:function(a){var b=MathJax.Extension[this.extension];b&&(b.Enable(!0,!0),MathJax.Menu.saveCookie())}});i.Register(j("collapsible","Collapsible Math","[a11y]/collapsible.js","collapsible")),i.Register(j("autocollapse","Auto Collapse","[a11y]/auto-collapse.js","auto-collapse")),i.Register(j("explorer","Explorer","[a11y]/explorer.js","explorer",!0)),i.AddDefaults(),a.Register.StartupHook("End Extensions",function(){a.Register.StartupHook("MathMenu Ready",function(){i.Startup(),a.Startup.signal.Post("Accessibility Menu Ready")},5)},5),MathJax.Callback.Queue(["LoadExtensions",i],["loadComplete",MathJax.Ajax,"[a11y]/accessibility-menu.js"])}(MathJax.Hub,MathJax.Extension);
\ No newline at end of file
diff --git a/filter/mathjaxloader/contrib/a11y/auto-collapse.js b/filter/mathjaxloader/contrib/a11y/auto-collapse.js
new file mode 100644 (file)
index 0000000..1987944
--- /dev/null
@@ -0,0 +1 @@
+!function(a){var b=a.config.menuSettings,c={},d=MathJax.Ajax.config.path;d.a11y||(d.a11y=d.Contrib?d.Contrib+"/a11y":(String(location.protocol).match(/^https?:/)?"":"http:")+"//cdn.mathjax.org/mathjax/contrib/a11y");var e=MathJax.Extension["auto-collapse"]={version:"1.1",config:a.CombineConfig("auto-collapse",{disabled:!1}),dependents:[],Enable:function(d,e){b.autocollapse=!0,e&&(c.autocollapse=!0),this.config.disabled=!1,MathJax.Extension.collapsible.Enable(!1,e),d&&a.Queue(["Reprocess",a],["CollapseWideMath",this])},Disable:function(d,e){b.autocollapse=!1,e&&(c.autocollapse=!1),this.config.disabled=!0;for(var f=this.dependents.length-1;f>=0;f--){var g=this.dependents[f];g.Disable&&g.Disable(!1,e)}d&&a.Queue(["Rerender",a])},Dependent:function(a){this.dependents.push(a)},Startup:function(){var b=MathJax.Extension.collapsible;b&&b.Dependent(this),a.postInputHooks.Add(["Filter",e],150),a.Queue(function(){return e.CollapseWideMath()}),window.addEventListener?window.addEventListener("resize",e.resizeHandler,!1):window.attachEvent?window.attachEvent("onresize",e.resizeHandler):window.onresize=e.resizeHandler},Filter:function(a,b,c){a.enriched&&!this.config.disabled&&("block"===a.root.Get("display")||c.parentNode.childNodes.length<=3)&&(a.root.SRE={action:this.Actions(a.root)})},Actions:function(a){var b=[];return this.getActions(a,0,b),this.sortActions(b)},getActions:function(a,b,c){if(!a.isToken&&a.data){b++;for(var d=0,e=a.data.length;d<e;d++)if(a.data[d]){var f=a.data[d];f.collapsible?(c[b]||(c[b]=[]),c[b].push(f),this.getActions(f.data[1],b,c)):this.getActions(f,b,c)}}},sortActions:function(a){for(var b=[],c=0,d=a.length;c<d;c++)a[c]&&(b=b.concat(a[c].sort(this.sortActionsBy)));return b},sortActionsBy:function(a,b){return a=a.data[1].complexity,b=b.data[1].complexity,a<b?-1:a>b?1:0},CollapseWideMath:function(b){if(!this.config.disabled){this.GetContainerWidths(b);var c=a.getAllJax(b),d={collapse:[],jax:c,m:c.length,i:0,changed:!1};return this.collapseState(d)}},collapseState:function(b){for(var c=b.collapse;b.i<b.m;){var d=b.jax[b.i],e=d.root.SRE;if(b.changed=!1,e&&e.action.length&&(e.cwidth<e.m||e.cwidth>e.M)){var f=this.getActionWidths(d,b);if(f)return f;this.collapseActions(e,b),b.changed&&c.push(d.SourceElement())}b.i++}if(0!==c.length)return 1===c.length&&(c=c[0]),a.Rerender(c)},collapseActions:function(a,b){for(var c=a.width,d=c,e=1e6,f=a.action.length-1;f>=0;f--){var g=a.action[f],h=g.selection;c>a.cwidth?(g.selection=1,d=g.SREwidth,e=c):g.selection=2,c=g.SREwidth,a.DOMupdate?document.getElementById(g.id).setAttribute("selection",g.selection):g.selection!==h&&(b.changed=!0)}a.m=d,a.M=e},getActionWidths:function(a,b){if(!a.root.SRE.actionWidths){MathJax.OutputJax[a.outputJax].getMetrics(a);try{this.computeActionWidths(a)}catch(a){if(!a.restart)throw a;return MathJax.Callback.After(["collapseState",this,b],a.restart)}b.changed=!0}return null},computeActionWidths:function(a){var b,c=a.root.SRE,d=c.action,e={};for(c.width=a.sreGetRootWidth(e),b=d.length-1;b>=0;b--)d[b].selection=2;for(b=d.length-1;b>=0;b--){var f=d[b];null==f.SREwidth&&(f.selection=1,f.SREwidth=a.sreGetActionWidth(e,f))}c.actionWidths=!0},GetContainerWidths:function(b){var c,d,e,f,g,h=a.getAllJax(b),i=MathJax.HTML.Element("span",{style:{display:"block"}}),j=[];for(c=0,d=h.length;c<d;c++)f=h[c],g=f.root,SRE=g.SRE,SRE&&SRE.action.length&&(null==SRE.width&&(f.sreGetMetrics(),SRE.m=SRE.width,SRE.M=1e6),e=f.SourceElement(),e.previousSibling.style.display="none",e.parentNode.insertBefore(i.cloneNode(!1),e),j.push([f,e]));for(c=0,d=j.length;c<d;c++)f=j[c][0],e=j[c][1],e.previousSibling.offsetWidth&&(f.root.SRE.cwidth=e.previousSibling.offsetWidth*f.root.SRE.em);for(c=0,d=j.length;c<d;c++)f=j[c][0],e=j[c][1],e.parentNode.removeChild(e.previousSibling),e.previousSibling.style.display=""},timer:null,running:!1,retry:!1,saved_delay:0,resizeHandler:function(a){if(!e.config.disabled){if(e.running)return void(e.retry=!0);e.timer&&clearTimeout(e.timer),e.timer=setTimeout(e.resizeAction,100)}},resizeAction:function(){e.timer=null,e.running=!0,a.Queue(function(){e.saved_delay=a.processSectionDelay,a.processSectionDelay=0},["CollapseWideMath",e],["resizeCheck",e])},resizeCheck:function(){e.running=!1,a.processSectionDelay=e.saved_delay,e.retry&&(e.retry=!1,setTimeout(e.resizeHandler,0))}};a.Register.StartupHook("End Extensions",function(){null==b.autocollapse?b.autocollapse=!e.config.disabled:e.config.disabled=!b.autocollapse,a.Register.StartupHook("MathMenu Ready",function(){c=MathJax.Menu.cookie;var a,d=function(a){e[b.autocollapse?"Enable":"Disable"](!0,!0),MathJax.Menu.saveCookie()},f=MathJax.Menu.ITEM,g=MathJax.Menu.menu,h=f.CHECKBOX(["AutoCollapse","Auto Collapse"],"autocollapse",{action:d}),i=(g.FindId("Accessibility")||{}).submenu;i?(a=i.IndexOfId("AutoCollapse"),null!==a?i.items[a]=h:(a=i.IndexOfId("CollapsibleMath"),i.items.splice(a+1,0,h))):(a=g.IndexOfId("CollapsibleMath"),g.items.splice(a+1,0,h)),e[b.autocollapse?"Enable":"Disable"]()},25)},25)}(MathJax.Hub),MathJax.ElementJax.Augment({sreGetMetrics:function(){MathJax.OutputJax[this.outputJax].sreGetMetrics(this,this.root.SRE)},sreGetRootWidth:function(a){return MathJax.OutputJax[this.outputJax].sreGetRootWidth(this,a)},sreGetActionWidth:function(a,b){return MathJax.OutputJax[this.outputJax].sreGetActionWidth(this,a,b)}}),MathJax.OutputJax.Augment({getMetrics:function(){},sreGetMetrics:function(a,b){b.cwidth=1e6,b.width=0,b.em=12},sreGetRootWidth:function(a,b){return 0},sreGetActionWidth:function(a,b,c){return 0}}),MathJax.Hub.Register.StartupHook("HTML-CSS Jax Ready",function(){MathJax.OutputJax["HTML-CSS"].Augment({sreGetMetrics:function(a,b){b.width=a.root.data[0].HTMLspanElement().parentNode.bbox.w,b.em=1/a.HTMLCSS.em/a.HTMLCSS.scale},sreGetRootWidth:function(a,b){var c=a.root.data[0].HTMLspanElement();return b.box=c.parentNode,b.box.bbox.w},sreGetActionWidth:function(a,b,c){return a.root.data[0].toHTML(b.box).bbox.w}})}),MathJax.Hub.Register.StartupHook("SVG Jax Ready",function(){MathJax.Hub.Config({SVG:{addMMLclasses:!0}}),MathJax.OutputJax.SVG.Augment({getMetrics:function(a){this.em=MathJax.ElementJax.mml.mbase.prototype.em=a.SVG.em,this.ex=a.SVG.ex,this.linebreakWidth=a.SVG.lineWidth,this.cwidth=a.SVG.cwidth},sreGetMetrics:function(a,b){b.width=a.root.SVGdata.w/1e3,b.em=1/a.SVG.em},sreGetRootWidth:function(a,b){return b.span=document.getElementById(a.inputID+"-Frame"),a.root.SVGdata.w/1e3},sreGetActionWidth:function(a,b,c){this.mathDiv=b.span,b.span.appendChild(this.textSVG);try{a.root.data[0].toSVG()}catch(a){var d=a}if(b.span.removeChild(this.textSVG),d)throw d;return a.root.data[0].SVGdata.w/1e3}})}),MathJax.Hub.Register.StartupHook("CommonHTML Jax Ready",function(){MathJax.OutputJax.CommonHTML.Augment({sreGetMetrics:function(a,b){b.width=a.root.CHTML.w,b.em=1/a.CHTML.em/a.CHTML.scale},sreGetRootWidth:function(a,b){return b.span=document.getElementById(a.inputID+"-Frame").firstChild,b.tmp=document.createElement("span"),b.tmp.className=b.span.className,a.root.CHTML.w/a.CHTML.scale},sreGetActionWidth:function(a,b,c){b.span.parentNode.replaceChild(b.tmp,b.span),MathJax.OutputJax.CommonHTML.CHTMLnode=b.tmp;try{a.root.data[0].toCommonHTML(b.tmp)}catch(a){var d=a}if(b.tmp.parentNode.replaceChild(b.span,b.tmp),d)throw d;return a.root.data[0].CHTML.w/a.CHTML.scale}})}),MathJax.Hub.Register.StartupHook("NativeMML Jax Ready",function(){MathJax.OutputJax.NativeMML.Augment({sreGetMetrics:function(a,b){var c=document.getElementById(a.inputID+"-Frame");b.width=c.offsetWidth,b.em=1,b.DOMupdate=!0},sreGetRootWidth:function(a,b){return b.span=document.getElementById(a.inputID+"-Frame").firstChild,b.span.offsetWidth},sreGetActionWidth:function(a,b,c){var d=document.getElementById(c.id);d.setAttribute("selection",1);var e=b.span.offsetWidth;return e}})}),MathJax.Ajax.Require("[a11y]/collapsible.js"),MathJax.Hub.Register.StartupHook("Collapsible Ready",function(){MathJax.Extension["auto-collapse"].Startup(),MathJax.Hub.Startup.signal.Post("Auto Collapse Ready"),MathJax.Ajax.loadComplete("[a11y]/auto-collapse.js")});
\ No newline at end of file
diff --git a/filter/mathjaxloader/contrib/a11y/collapsible.js b/filter/mathjaxloader/contrib/a11y/collapsible.js
new file mode 100644 (file)
index 0000000..4d1e097
--- /dev/null
@@ -0,0 +1 @@
+!function(a){var b,c=a.config.menuSettings,d={},e=1e7,f="data-semantic-complexity",g=MathJax.Ajax.config.path;g.a11y||(g.a11y=g.Contrib?g.Contrib+"/a11y":(String(location.protocol).match(/^https?:/)?"":"http:")+"//cdn.mathjax.org/mathjax/contrib/a11y");var h=MathJax.Extension.collapsible={version:"1.1",config:a.CombineConfig("collapsible",{disabled:!1}),dependents:[],COMPLEXATTR:f,COMPLEXITY:{TEXT:.5,TOKEN:.5,CHILD:1,SCRIPT:.8,SQRT:2,SUBSUP:2,UNDEROVER:2,FRACTION:2,ACTION:2,PHANTOM:0,XML:2,GLYPH:2},COLLAPSE:{identifier:3,number:3,text:10,infixop:15,relseq:15,multirel:15,fenced:18,bigop:20,integral:20,fraction:12,sqrt:9,root:12,vector:15,matrix:15,cases:15,superscript:9,subscript:9,subsup:9,punctuated:{endpunct:e,startpunct:e,default:12}},MARKER:{identifier:"x",number:"#",text:"...",appl:{"limit function":"lim",default:"f()"},fraction:"/",sqrt:"\u221a",root:"\u221a",superscript:"\u25fd\u02d9",subscript:"\u25fd.",subsup:"\u25fd:",vector:{binomial:"(:)",determinant:"|:|",default:"\u27e8:\u27e9"},matrix:{squarematrix:"[::]",rowvector:"\u27e8\u22ef\u27e9",columnvector:"\u27e8\u22ee\u27e9",determinant:"|::|",default:"(::)"},cases:"{:",infixop:{addition:"+",subtraction:"\u2212",multiplication:"\u22c5",implicit:"\u22c5",default:"+"},punctuated:{text:"...",default:","}},Enable:function(b,e){c.collapsible=!0,e&&(d.collapsible=!0),this.config.disabled=!1,MathJax.Extension["semantic-enrich"].Enable(!1,e),b&&a.Queue(["Reprocess",a])},Disable:function(b,e){c.collapsible=!1,e&&(d.collapsible=!1),this.config.disabled=!0;for(var f=this.dependents.length-1;f>=0;f--){var g=this.dependents[f];g.Disable&&g.Disable(!1,e)}b&&a.Queue(["Reprocess",a])},Dependent:function(a){this.dependents.push(a)},Startup:function(){b=MathJax.ElementJax.mml;var c=MathJax.Extension["semantic-enrich"];c&&c.Dependent(this),a.postInputHooks.Add(["Filter",h],100)},Filter:function(a,b,c){a.enriched&&!this.config.disabled&&(a.root=a.root.Collapse(),a.root.inputID=c.id)},Marker:function(a){return b.mtext("\u25c2"+a+"\u25b8").With({mathcolor:"blue",attr:{},attrNames:[]})},MakeAction:function(a,c){var d=b.maction(a).With({id:this.getActionID(),actiontype:"toggle",complexity:a.getComplexity(),collapsible:!0,attrNames:["id","actiontype","selection",f],attr:{},selection:2});if(d.attr[f]=d.complexity,"math"===c.type){for(var e,g=b.mrow().With({data:c.data,complexity:c.complexity,attrNames:[],attr:{}}),h=c.attrNames.length-1;e=c.attrNames[h];h--)"data-semantic-"===e.substr(0,14)&&(g.attr[e]=c.attr[e],g.attrNames.push(e),delete c.attr[e],c.attrNames.splice(h,1));g.complexity=c.complexity,d.Append(g),c.data=[],c.Append(d),c.complexity=d.complexity,d=c}else d.Append(c);return d},actionID:1,getActionID:function(){return"MJX-Collapse-"+this.actionID++},Collapse:function(a){a.getComplexity();var b=(a.attr||{})["data-semantic-type"];if(b)if(this["Collapse_"+b])a=this["Collapse_"+b](a);else if(this.COLLAPSE[b]&&this.MARKER[b]){var c=a.attr["data-semantic-role"],d=this.COLLAPSE[b];if("number"!=typeof d&&(d=d[c]||d.default),a.complexity>d){var e=this.MARKER[b];"string"!=typeof e&&(e=e[c]||e.default),a=this.MakeAction(this.Marker(e),a)}}return a},UncollapseChild:function(a,b,c){if(null==c&&(c=1),this.SplitAttribute(a,"children").length===c){var d=1===a.data.length&&a.data[0].inferred?a.data[0]:a;if(d&&d.data[b]&&d.data[b].collapsible)return d.SetData(b,d.data[b].data[1]),a.complexity=d.complexity=null,a.getComplexity(),1}return 0},FindChildText:function(a,b){var c=this.FindChild(a,b);return c?c.data.join(""):"?"},FindChild:function(a,b){if(a){if(a.attr&&a.attr["data-semantic-id"]===b)return a;if(!a.isToken)for(var c=0,d=a.data.length;c<d;c++){var e=this.FindChild(a.data[c],b);if(e)return e}}return null},SplitAttribute:function(a,b){return(a.attr["data-semantic-"+b]||"").split(/,/)},Collapse_fenced:function(a){if(this.UncollapseChild(a,1),a.complexity>this.COLLAPSE.fenced&&"leftright"===a.attr["data-semantic-role"]){var b=a.data[0].data.join("")+a.data[a.data.length-1].data.join("");a=this.MakeAction(this.Marker(b),a)}return a},Collapse_appl:function(a){if(this.UncollapseChild(a,2,2)){var b=this.MARKER.appl;b=b[a.attr["data-semantic-role"]]||b.default,a=this.MakeAction(this.Marker(b),a)}return a},Collapse_sqrt:function(a){return this.UncollapseChild(a,0),a.complexity>this.COLLAPSE.sqrt&&(a=this.MakeAction(this.Marker(this.MARKER.sqrt),a)),a},Collapse_root:function(a){return this.UncollapseChild(a,0),a.complexity>this.COLLAPSE.sqrt&&(a=this.MakeAction(this.Marker(this.MARKER.sqrt),a)),a},Collapse_enclose:function(a){if(1===this.SplitAttribute(a,"children").length){var b=1===a.data.length&&a.data[0].inferred?a.data[0]:a;if(b.data[0]&&b.data[0].collapsible){var c=b.data[0];b.SetData(0,c.data[1]),c.SetData(1,a),a=c}}return a},Collapse_bigop:function(a){if(a.complexity>this.COLLAPSE.bigop||"mo"!==a.data[0].type){var b=this.SplitAttribute(a,"content").pop(),c=h.FindChildText(a,b);a=this.MakeAction(this.Marker(c),a)}return a},Collapse_integral:function(a){if(a.complexity>this.COLLAPSE.integral||"mo"!==a.data[0].type){var b=this.SplitAttribute(a,"content")[0],c=h.FindChildText(a,b);a=this.MakeAction(this.Marker(c),a)}return a},Collapse_relseq:function(a){if(a.complexity>this.COLLAPSE.relseq){var b=this.SplitAttribute(a,"content"),c=h.FindChildText(a,b[0]);b.length>1&&(c+="\u22ef"),a=this.MakeAction(this.Marker(c),a)}return a},Collapse_multirel:function(a){if(a.complexity>this.COLLAPSE.multirel){var b=this.SplitAttribute(a,"content"),c=h.FindChildText(a,b[0])+"\u22ef";a=this.MakeAction(this.Marker(c),a)}return a},Collapse_superscript:function(a){return this.UncollapseChild(a,0,2),a.complexity>this.COLLAPSE.superscript&&(a=this.MakeAction(this.Marker(this.MARKER.superscript),a)),a},Collapse_subscript:function(a){return this.UncollapseChild(a,0,2),a.complexity>this.COLLAPSE.subscript&&(a=this.MakeAction(this.Marker(this.MARKER.subscript),a)),a},Collapse_subsup:function(a){return this.UncollapseChild(a,0,3),a.complexity>this.COLLAPSE.subsup&&(a=this.MakeAction(this.Marker(this.MARKER.subsup),a)),a}};a.Register.StartupHook("End Extensions",function(){null==c.collapsible?c.collapsible=!h.config.disabled:h.config.disabled=!c.collapsible,a.Register.StartupHook("MathMenu Ready",function(){d=MathJax.Menu.cookie;var a,b=function(a){h[c.collapsible?"Enable":"Disable"](!0,!0),MathJax.Menu.saveCookie()},e=MathJax.Menu.ITEM,f=MathJax.Menu.menu,g=e.CHECKBOX(["CollapsibleMath","Collapsible Math"],"collapsible",{action:b}),i=(f.FindId("Accessibility")||{}).submenu;i?(a=i.IndexOfId("CollapsibleMath"),null!==a?i.items[a]=g:i.items.push(e.RULE(),g)):(a=f.IndexOfId("About"),f.items.splice(a,0,g,e.RULE()))},15)},15)}(MathJax.Hub),MathJax.Ajax.Require("[a11y]/semantic-enrich.js"),MathJax.Hub.Register.StartupHook("Semantic Enrich Ready",function(){var a=MathJax.ElementJax.mml,b=MathJax.Extension.collapsible,c=b.COMPLEXITY,d=b.COMPLEXATTR;b.Startup(),a.mbase.Augment({Collapse:function(){return b.Collapse(this)},getComplexity:function(){if(null==this.complexity){var a=0;if(this.isToken)a=c.TEXT*this.data.join("").length+c.TOKEN;else{for(var b=0,e=this.data.length;b<e;b++)this.data[b]&&(this.SetData(b,this.data[b].Collapse()),a+=this.data[b].complexity);e>1&&(a+=e*c.CHILD)}!this.attrNames||"complexity"in this||this.attrNames.push(d),this.attr&&(this.attr[d]=a),this.complexity=a}return this.complexity},reportComplexity:function(){!this.attr||!this.attrNames||d in this.attr||(this.attrNames.push(d),this.attr[d]=this.complexity)}}),a.mfrac.Augment({getComplexity:function(){return null==this.complexity&&(this.SUPER(arguments).getComplexity.call(this),this.complexity*=c.SCRIPT,this.complexity+=c.FRACTION,this.attr[d]=this.complexity),this.complexity}}),a.msqrt.Augment({getComplexity:function(){return null==this.complexity&&(this.SUPER(arguments).getComplexity.call(this),this.complexity+=c.SQRT,this.attr[d]=this.complexity),this.complexity}}),a.mroot.Augment({getComplexity:function(){return null==this.complexity&&(this.SUPER(arguments).getComplexity.call(this),this.complexity-=(1-c.SCRIPT)*this.data[1].getComplexity(),this.complexity+=c.SQRT,this.attr[d]=this.complexity),this.complexity}}),a.msubsup.Augment({getComplexity:function(){if(null==this.complexity){var a=0;this.data[this.sub]&&(a=this.data[this.sub].getComplexity()+c.CHILD),this.data[this.sup]&&(a=Math.max(this.data[this.sup].getComplexity(),a)),a*=c.SCRIPT,this.data[this.sub]&&(a+=c.CHILD),this.data[this.sup]&&(a+=c.CHILD),this.data[this.base]&&(a+=this.data[this.base].getComplexity()+c.CHILD),this.complexity=a+c.SUBSUP,this.reportComplexity()}return this.complexity}}),a.munderover.Augment({getComplexity:function(){if(null==this.complexity){var a=0;this.data[this.sub]&&(a=this.data[this.sub].getComplexity()+c.CHILD),this.data[this.sup]&&(a=Math.max(this.data[this.sup].getComplexity(),a)),a*=c.SCRIPT,this.data[this.base]&&(a=Math.max(this.data[this.base].getComplexity(),a)),this.data[this.sub]&&(a+=c.CHILD),this.data[this.sup]&&(a+=c.CHILD),this.data[this.base]&&(a+=c.CHILD),this.complexity=a+c.UNDEROVER,this.reportComplexity()}return this.complexity}}),a.mphantom.Augment({getComplexity:function(){return this.complexity=c.PHANTOM,this.reportComplexity(),this.complexity}}),a.ms.Augment({getComplexity:function(){return this.SUPER(arguments).getComplexity.call(this),this.complexity+=this.Get("lquote").length*c.TEXT,this.complexity+=this.Get("rquote").length*c.TEXT,this.attr[d]=this.complexity,this.complexity}}),a.menclose.Augment({getComplexity:function(){return null==this.complexity&&(this.SUPER(arguments).getComplexity.call(this),this.complexity+=c.ACTION,this.attr[d]=this.complexity),this.complexity}}),a.maction.Augment({getComplexity:function(){return this.complexity=(this.collapsible?this.data[0]:this.selected()).getComplexity(),this.reportComplexity(),this.complexity}}),a.semantics.Augment({getComplexity:function(){return null==this.complexity&&(this.complexity=this.data[0]?this.data[0].getComplexity():0,this.reportComplexity()),this.complexity}}),a["annotation-xml"].Augment({getComplexity:function(){return this.complexity=c.XML,this.reportComplexity(),this.complexity}}),a.annotation.Augment({getComplexity:function(){return this.complexity=c.XML,this.reportComplexity(),this.complexity}}),a.mglyph.Augment({getComplexity:function(){return this.complexity=c.GLYPH,this.reportComplexity(),this.complexity}}),MathJax.Hub.Startup.signal.Post("Collapsible Ready"),MathJax.Ajax.loadComplete("[a11y]/collapsible.js")});
\ No newline at end of file
diff --git a/filter/mathjaxloader/contrib/a11y/explorer.js b/filter/mathjaxloader/contrib/a11y/explorer.js
new file mode 100644 (file)
index 0000000..1b694c6
--- /dev/null
@@ -0,0 +1 @@
+MathJax.Hub.Register.StartupHook("Sre Ready",function(){var a,b,c=MathJax.Hub.config.menuSettings,d={};MathJax.Hub.Register.StartupHook("MathEvents Ready",function(){a=MathJax.Extension.MathEvents.Event.False,b=MathJax.Extension.MathEvents.Event.KEY});var e=MathJax.Extension.explorer={version:"1.1",dependents:[],default:{walker:"syntactic",highlight:"none",background:"blue",foreground:"black",speech:!0,generation:"lazy",subtitle:!1,ruleset:"mathspeak-default"},eagerComplexity:80,prefix:"Assistive-",hook:null,oldrules:null,addMenuOption:function(a,b){c[e.prefix+a]=b},addDefaults:function(){for(var a,b=MathJax.Hub.CombineConfig("explorer",e.default),d=Object.keys(b),f=0;a=d[f];f++)"undefined"==typeof c[e.prefix+a]&&e.addMenuOption(a,b[a]);e.setSpeechOption(),g.Reset()},setOption:function(a,b){c[e.prefix+a]!==b&&(e.addMenuOption(a,b),g.Reset())},getOption:function(a){return c[e.prefix+a]},speechOption:function(a){e.oldrules!==a.value&&(e.setSpeechOption(),g.Regenerate())},setSpeechOption:function(){var a=c[e.prefix+"ruleset"],b=a.split("-");sre.System.getInstance().setupEngine({domain:e.Domain(b[0]),style:b[1],rules:e.RuleSet(b[0])}),e.oldrules=a},Domain:function(a){switch(a){case"chromevox":return"default";case"mathspeak":default:return"mathspeak"}},RuleSet:function(a){switch(a){case"chromevox":return["AbstractionRules","SemanticTreeRules"];case"mathspeak":default:return["AbstractionRules","MathspeakRules"]}},hook:null,Enable:function(a,b){c.explorer=!0,b&&(d.explorer=!0),MathJax.Extension.collapsible.Enable(!1,b),MathJax.Extension.AssistiveMML&&(MathJax.Extension.AssistiveMML.config.disabled=!0,c.assistiveMML=!1,b&&(d.assistiveMML=!1)),this.DisableMenus(!1),this.hook||(this.hook=MathJax.Hub.Register.MessageHook("New Math",["Register",this.Explorer])),a&&MathJax.Hub.Queue(["Reprocess",MathJax.Hub])},Disable:function(a,b){c.explorer=!1,b&&(d.explorer=!1),this.DisableMenus(!0),this.hook&&(MathJax.Hub.UnRegister.MessageHook(this.hook),this.hook=null);for(var e=this.dependents.length-1;e>=0;e--){var f=this.dependents[e];f.Disable&&f.Disable(!1,b)}},DisableMenus:function(a){if(MathJax.Menu){var b=MathJax.Menu.menu.FindId("Explorer");if(b)for(var c,d=b.submenu.items,e=2;c=d[e];e++)c.disabled=a}},Dependent:function(a){this.dependents.push(a)}},f=MathJax.Object.Subclass({div:null,inner:null,Init:function(){this.div=f.Create("assertive"),this.inner=MathJax.HTML.addElement(this.div,"div")},Add:function(){f.added||(document.body.appendChild(this.div),f.added=!0)},Show:function(a,b){this.div.classList.add("MJX_LiveRegion_Show");var c=a.getBoundingClientRect(),d=c.bottom+10+window.pageYOffset,e=c.left+window.pageXOffset;this.div.style.top=d+"px",this.div.style.left=e+"px";var f=b.colorString();this.inner.style.backgroundColor=f.background,this.inner.style.color=f.foreground},Hide:function(a){this.div.classList.remove("MJX_LiveRegion_Show")},Clear:function(){this.Update(""),this.inner.style.top="",this.inner.style.backgroundColor=""},Update:function(a){e.getOption("speech")&&f.Update(this.inner,a)}},{ANNOUNCE:"Navigatable Math in page. Explore with shift space and arrow keys. Expand or collapse elements hitting enter.",announced:!1,added:!1,styles:{".MJX_LiveRegion":{position:"absolute",top:"0",height:"1px",width:"1px",padding:"1px",overflow:"hidden"},".MJX_LiveRegion_Show":{top:"0",position:"absolute",width:"auto",height:"auto",padding:"0px 0px",opacity:1,"z-index":"202",left:0,right:0,margin:"0 auto","background-color":"white","box-shadow":"0px 10px 20px #888",border:"2px solid #CCCCCC"}},Create:function(a){var b=MathJax.HTML.Element("div",{className:"MJX_LiveRegion"});return b.setAttribute("aria-live",a),b},Update:MathJax.Hub.Browser.isPC?function(a,b){a.textContent="",setTimeout(function(){a.textContent=b},100)}:function(a,b){a.textContent="",a.textContent=b},Announce:function(){if(e.getOption("speech")){f.announced=!0,MathJax.Ajax.Styles(f.styles);var a=f.Create("polite");document.body.appendChild(a),f.Update(a,f.ANNOUNCE),setTimeout(function(){document.body.removeChild(a)},1e3)}}});MathJax.Extension.explorer.LiveRegion=f;var g=MathJax.Extension.explorer.Explorer={liveRegion:f(),walker:null,highlighter:null,hoverer:null,flamer:null,speechDiv:null,earconFile:MathJax.Ajax.config.path.a11y+"/invalid_keypress"+(["Firefox","Chrome","Opera"].indexOf(MathJax.Hub.Browser.name)!==-1?".ogg":".mp3"),expanded:!1,focusoutEvent:MathJax.Hub.Browser.isFirefox?"blur":"focusout",focusinEvent:"focus",ignoreFocusOut:!1,jaxCache:{},messageID:null,Reset:function(){g.FlameEnriched()},Register:function(a){if(e.hook){var b=document.getElementById(a[1]);if(b&&b.id){var c=MathJax.Hub.getJaxFor(b.id);c&&c.enriched&&(g.StateChange(b.id,c),g.liveRegion.Add(),g.AddEvent(b))}}},StateChange:function(a,b){g.GetHighlighter(.2);var c=g.jaxCache[a];c&&c===b.root||(c&&g.highlighter.resetState(a+"-Frame"),g.jaxCache[a]=b.root)},AddAria:function(a){a.setAttribute("role","application"),a.setAttribute("aria-label","Math")},AddHook:function(a){g.RemoveHook(),g.hook=MathJax.Hub.Register.MessageHook("End Math",function(b){var c=b[1].id+"-Frame",d=document.getElementById(c);a&&c===g.expanded&&(g.ActivateWalker(d,a),d.focus(),g.expanded=!1)})},RemoveHook:function(){g.hook&&(MathJax.Hub.UnRegister.MessageHook(g.hook),g.hook=null)},AddMessage:function(){return MathJax.Message.Set("Generating Speech Output")},RemoveMessage:function(a){a&&MathJax.Message.Clear(a)},AddEvent:function(a){var b=a.id+"-Frame",c=a.previousSibling;if(c){var d=c.id!==b?c.firstElementChild:c;g.AddAria(d),g.AddMouseEvents(d),"MathJax_MathML"===d.className&&(d=d.firstElementChild),d&&(d.onkeydown=g.Keydown,g.Flame(d),d.addEventListener(g.focusinEvent,function(a){e.hook&&(f.announced||f.Announce())}),d.addEventListener(g.focusoutEvent,function(a){if(e.hook)return g.ignoreFocusOut&&(g.ignoreFocusOut=!1,"enter"===g.walker.moved)?void a.target.focus():void(g.walker&&g.DeactivateWalker())}),e.getOption("speech")&&g.AddSpeech(d))}},AddSpeech:function(a){var b=a.id,c=MathJax.Hub.getJaxFor(b),d=c.root.toMathML();if(a.getAttribute("haslabel")||g.AddMathLabel(d,b),!a.getAttribute("hasspeech"))switch(e.getOption("generation")){case"eager":g.AddSpeechEager(d,b);break;case"mixed":var f=a.querySelectorAll("[data-semantic-complexity]");f.length>=e.eagerComplexity&&g.AddSpeechEager(d,b);break;case"lazy":}},AddSpeechLazy:function(a){var b=new sre.TreeSpeechGenerator;b.setRebuilt(g.walker.rebuilt),b.getSpeech(g.walker.rootNode,g.walker.xml),a.setAttribute("hasspeech","true")},AddSpeechEager:function(a,b){g.MakeSpeechTask(a,b,sre.TreeSpeechGenerator,function(a,b){a.setAttribute("hasspeech","true")},5)},AddMathLabel:function(a,b){g.MakeSpeechTask(a,b,sre.SummarySpeechGenerator,function(a,b){a.setAttribute("haslabel","true"),a.setAttribute("aria-label",b)},5)},MakeSpeechTask:function(a,b,c,d,e){var f=g.AddMessage();setTimeout(function(){var e=new c,h=document.getElementById(b),i=new sre.DummyWalker(h,e,g.highlighter,a),j=i.speech();j&&d(h,j),g.RemoveMessage(f)},e)},Keydown:function(c){if(c.keyCode===b.ESCAPE){if(!g.walker)return;return g.RemoveHook(),g.DeactivateWalker(),void a(c)}if(g.walker&&g.walker.isActive()){var d=g.walker.move(c.keyCode);if(null===d)return;if(d){if("expand"===g.walker.moved){if(g.expanded=g.walker.node.id,MathJax.Hub.Browser.isEdge)return g.ignoreFocusOut=!0,void g.DeactivateWalker();if(MathJax.Hub.Browser.isFirefox||MathJax.Hub.Browser.isMSIE)return void g.DeactivateWalker()}g.liveRegion.Update(g.walker.speech()),g.Highlight()}else g.PlayEarcon();return void a(c)}var f=c.target;if(c.keyCode===b.SPACE){if(c.shiftKey&&e.hook){var h=MathJax.Hub.getJaxFor(f);g.ActivateWalker(f,h),g.AddHook(h)}else MathJax.Extension.MathEvents.Event.ContextMenu(c,f);return void a(c)}},GetHighlighter:function(a){g.highlighter=sre.HighlighterFactory.highlighter({color:e.getOption("background"),alpha:a},{color:e.getOption("foreground"),alpha:1},{renderer:MathJax.Hub.outputJax["jax/mml"][0].id,browser:MathJax.Hub.Browser.name})},AddMouseEvents:function(a){sre.HighlighterFactory.addEvents(a,{mouseover:g.MouseOver,mouseout:g.MouseOut},{renderer:MathJax.Hub.outputJax["jax/mml"][0].id,browser:MathJax.Hub.Browser.name})},MouseOver:function(b){if("none"!==e.getOption("highlight")){if("hover"===e.getOption("highlight")){var c=b.currentTarget;g.GetHighlighter(.1),g.highlighter.highlight([c]),g.hoverer=!0}a(b)}},MouseOut:function(b){return g.hoverer&&(g.highlighter.unhighlight(),g.hoverer=!1),a(b)},Flame:function(a){if("flame"===e.getOption("highlight"))return g.GetHighlighter(.05),g.highlighter.highlightAll(a),void(g.flamer=!0)},UnFlame:function(){g.flamer&&(g.highlighter.unhighlightAll(),g.flamer=null)},FlameEnriched:function(){g.UnFlame();for(var a,b=0,c=MathJax.Hub.getAllJax();a=c[b];b++)g.Flame(a.SourceElement().previousSibling)},Walkers:{syntactic:sre.SyntaxWalker,semantic:sre.SemanticWalker,none:sre.DummyWalker},ActivateWalker:function(a,b){var c=e.getOption("speech"),d=g.Walkers[e.getOption("walker")]||g.Walkers.none,f=c?new sre.DirectSpeechGenerator:new sre.DummySpeechGenerator;g.GetHighlighter(.2),g.walker=new d(a,f,g.highlighter,b.root.toMathML()),c&&!a.getAttribute("hasspeech")&&g.AddSpeechLazy(a),g.walker.activate(),c&&(e.getOption("subtitle")&&g.liveRegion.Show(a,g.highlighter),g.liveRegion.Update(g.walker.speech())),g.Highlight(),g.ignoreFocusOut&&setTimeout(function(){g.ignoreFocusOut=!1},500)},DeactivateWalker:function(){g.liveRegion.Clear(),g.liveRegion.Hide(),g.Unhighlight(),g.currentHighlight=null,g.walker.deactivate(),g.walker=null},Highlight:function(){g.Unhighlight(),g.highlighter.highlight(g.walker.getFocus().getNodes())},Unhighlight:function(){g.highlighter.unhighlight()},PlayEarcon:function(){var a=new Audio(g.earconFile);a.play()},SpeechOutput:function(){g.Reset();var a=["Subtitles","Generation"];a.forEach(function(a){var b=MathJax.Menu.menu.FindId("Accessibility",a);b&&(b.disabled=!b.disabled)}),g.Regenerate()},Regenerate:function(){for(var a,b=0,c=MathJax.Hub.getAllJax();a=c[b];b++){var d=document.getElementById(a.inputID+"-Frame");d&&(d.removeAttribute("hasSpeech"),g.AddSpeech(d))}},Startup:function(){var a=MathJax.Extension.collapsible;a&&a.Dependent(e),e.addDefaults()}};MathJax.Hub.Register.StartupHook("End Extensions",function(){e[c.explorer===!1?"Disable":"Enable"](),MathJax.Hub.Startup.signal.Post("Explorer Ready"),MathJax.Hub.Register.StartupHook("MathMenu Ready",function(){d=MathJax.Menu.cookie;var a,b=function(a){e[c.explorer?"Enable":"Disable"](!0,!0),MathJax.Menu.saveCookie()},f=MathJax.Menu.ITEM,h=MathJax.Menu.menu,i={action:g.Reset},j={action:e.speechOption},k=f.SUBMENU(["Explorer","Explorer"],f.CHECKBOX(["Active","Active"],"explorer",{action:b}),f.RULE(),f.SUBMENU(["Walker","Walker"],f.RADIO(["nowalker","No walker"],"Assistive-walker",{value:"none"}),f.RADIO(["syntactic","Syntax walker"],"Assistive-walker"),f.RADIO(["semantic","Semantic walker"],"Assistive-walker")),f.SUBMENU(["Highlight","Highlight"],f.RADIO(["none","None"],"Assistive-highlight",i),f.RADIO(["hover","Hover"],"Assistive-highlight",i),f.RADIO(["flame","Flame"],"Assistive-highlight",i)),f.SUBMENU(["Background","Background"],f.RADIO(["blue","Blue"],"Assistive-background",i),f.RADIO(["red","Red"],"Assistive-background",i),f.RADIO(["green","Green"],"Assistive-background",i),f.RADIO(["yellow","Yellow"],"Assistive-background",i),f.RADIO(["cyan","Cyan"],"Assistive-background",i),f.RADIO(["magenta","Magenta"],"Assistive-background",i),f.RADIO(["white","White"],"Assistive-background",i),f.RADIO(["black","Black"],"Assistive-background",i)),f.SUBMENU(["Foreground","Foreground"],f.RADIO(["black","Black"],"Assistive-foreground",i),f.RADIO(["white","White"],"Assistive-foreground",i),f.RADIO(["magenta","Magenta"],"Assistive-foreground",i),f.RADIO(["cyan","Cyan"],"Assistive-foreground",i),f.RADIO(["yellow","Yellow"],"Assistive-foreground",i),f.RADIO(["green","Green"],"Assistive-foreground",i),f.RADIO(["red","Red"],"Assistive-foreground",i),f.RADIO(["blue","Blue"],"Assistive-foreground",i)),f.RULE(),f.CHECKBOX(["SpeechOutput","Speech Output"],"Assistive-speech",{action:g.SpeechOutput}),f.CHECKBOX(["Subtitles","Subtitles"],"Assistive-subtitle",{disabled:!c["Assistive-speech"]}),f.SUBMENU(["Generation","Generation"],f.RADIO(["eager","Eager"],"Assistive-generation",{action:g.Regenerate}),f.RADIO(["mixed","Mixed"],"Assistive-generation",{action:g.Regenerate}),f.RADIO(["lazy","Lazy"],"Assistive-generation",{action:g.Regenerate})),f.RULE(),f.SUBMENU(["Mathspeak","Mathspeak Rules"],f.RADIO(["mathspeak-default","Verbose"],"Assistive-ruleset",j),f.RADIO(["mathspeak-brief","Brief"],"Assistive-ruleset",j),f.RADIO(["mathspeak-sbrief","Superbrief"],"Assistive-ruleset",j)),f.SUBMENU(["Chromevox","ChromeVox Rules"],f.RADIO(["chromevox-default","Verbose"],"Assistive-ruleset",j),f.RADIO(["chromevox-short","Short"],"Assistive-ruleset",j),f.RADIO(["chromevox-alternative","Alternative"],"Assistive-ruleset",j))),l=(h.FindId("Accessibility")||{}).submenu;l?(a=l.IndexOfId("Explorer"),null!==a?l.items[a]=k:(a=l.IndexOfId("CollapsibleMath"),l.items.splice(a+1,0,k))):(a=h.IndexOfId("CollapsibleMath"),h.items.splice(a+1,0,k)),c.explorer||e.DisableMenus(!0)},20)},20)}),MathJax.Hub.Register.StartupHook("SVG Jax Ready",function(){var a=MathJax.OutputJax.SVG;if(parseFloat(a.version)<2.7){var b=a.getJaxFromMath;a.Augment({getJaxFromMath:function(a){return a.parentNode.className.match(/MathJax_SVG_Display/)&&(a=a.parentNode),b.call(this,a)}})}}),MathJax.Ajax.config.path.a11y||(MathJax.Ajax.config.path.a11y=(String(location.protocol).match(/^https?:/)?"":"http:")+"//cdn.mathjax.org/mathjax/contrib/a11y"),MathJax.Ajax.Require("[a11y]/collapsible.js"),MathJax.Hub.Register.StartupHook("Collapsible Ready",function(){MathJax.Extension.explorer.Explorer.Startup(),MathJax.Ajax.loadComplete("[a11y]/explorer.js")});
\ No newline at end of file
diff --git a/filter/mathjaxloader/contrib/a11y/invalid_keypress.mp3 b/filter/mathjaxloader/contrib/a11y/invalid_keypress.mp3
new file mode 100644 (file)
index 0000000..cba44de
Binary files /dev/null and b/filter/mathjaxloader/contrib/a11y/invalid_keypress.mp3 differ
diff --git a/filter/mathjaxloader/contrib/a11y/invalid_keypress.ogg b/filter/mathjaxloader/contrib/a11y/invalid_keypress.ogg
new file mode 100644 (file)
index 0000000..292cefd
Binary files /dev/null and b/filter/mathjaxloader/contrib/a11y/invalid_keypress.ogg differ
diff --git a/filter/mathjaxloader/contrib/a11y/mathjax-sre.js b/filter/mathjaxloader/contrib/a11y/mathjax-sre.js
new file mode 100644 (file)
index 0000000..c77a3a0
--- /dev/null
@@ -0,0 +1,624 @@
+var $jscomp={scope:{}};$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){if(c.get||c.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)};$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global?global:a};$jscomp.global=$jscomp.getGlobal(this);$jscomp.SYMBOL_PREFIX="jscomp_symbol_";
+$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};$jscomp.global.Symbol||($jscomp.global.Symbol=$jscomp.Symbol)};$jscomp.symbolCounter_=0;$jscomp.Symbol=function(a){return $jscomp.SYMBOL_PREFIX+(a||"")+$jscomp.symbolCounter_++};
+$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var a=$jscomp.global.Symbol.iterator;a||(a=$jscomp.global.Symbol.iterator=$jscomp.global.Symbol("iterator"));"function"!=typeof Array.prototype[a]&&$jscomp.defineProperty(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return $jscomp.arrayIterator(this)}});$jscomp.initSymbolIterator=function(){}};$jscomp.arrayIterator=function(a){var b=0;return $jscomp.iteratorPrototype(function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}})};
+$jscomp.iteratorPrototype=function(a){$jscomp.initSymbolIterator();a={next:a};a[$jscomp.global.Symbol.iterator]=function(){return this};return a};$jscomp.array=$jscomp.array||{};$jscomp.iteratorFromArray=function(a,b){$jscomp.initSymbolIterator();a instanceof String&&(a+="");var c=0,d={next:function(){if(c<a.length){var e=c++;return{value:b(e,a[e]),done:!1}}d.next=function(){return{done:!0,value:void 0}};return d.next()}};d[Symbol.iterator]=function(){return d};return d};
+$jscomp.polyfill=function(a,b,c,d){if(b){c=$jscomp.global;a=a.split(".");for(d=0;d<a.length-1;d++){var e=a[d];e in c||(c[e]={});c=c[e]}a=a[a.length-1];d=c[a];b=b(d);b!=d&&null!=b&&$jscomp.defineProperty(c,a,{configurable:!0,writable:!0,value:b})}};$jscomp.polyfill("Array.prototype.keys",function(a){return a?a:function(){return $jscomp.iteratorFromArray(this,function(a){return a})}},"es6-impl","es3");
+$jscomp.checkStringArgs=function(a,b,c){if(null==a)throw new TypeError("The 'this' value for String.prototype."+c+" must not be null or undefined");if(b instanceof RegExp)throw new TypeError("First argument to String.prototype."+c+" must not be a regular expression");return a+""};
+$jscomp.polyfill("String.prototype.repeat",function(a){return a?a:function(a){var b=$jscomp.checkStringArgs(this,null,"repeat");if(0>a||1342177279<a)throw new RangeError("Invalid count value");a|=0;for(var d="";a;)if(a&1&&(d+=b),a>>>=1)b+=b;return d}},"es6-impl","es3");$jscomp.findInternal=function(a,b,c){a instanceof String&&(a=String(a));for(var d=a.length,e=0;e<d;e++){var f=a[e];if(b.call(c,f,e,a))return{i:e,v:f}}return{i:-1,v:void 0}};
+$jscomp.polyfill("Array.prototype.find",function(a){return a?a:function(a,c){return $jscomp.findInternal(this,a,c).v}},"es6-impl","es3");var COMPILED=!0,goog=goog||{};goog.global=this;goog.isDef=function(a){return void 0!==a};goog.exportPath_=function(a,b,c){a=a.split(".");c=c||goog.global;a[0]in c||!c.execScript||c.execScript("var "+a[0]);for(var d;a.length&&(d=a.shift());)!a.length&&goog.isDef(b)?c[d]=b:c=c[d]?c[d]:c[d]={}};
+goog.define=function(a,b){var c=b;COMPILED||(goog.global.CLOSURE_UNCOMPILED_DEFINES&&Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_UNCOMPILED_DEFINES,a)?c=goog.global.CLOSURE_UNCOMPILED_DEFINES[a]:goog.global.CLOSURE_DEFINES&&Object.prototype.hasOwnProperty.call(goog.global.CLOSURE_DEFINES,a)&&(c=goog.global.CLOSURE_DEFINES[a]));goog.exportPath_(a,c)};goog.DEBUG=!0;goog.LOCALE="en";goog.TRUSTED_SITE=!0;goog.STRICT_MODE_COMPATIBLE=!1;goog.DISALLOW_TEST_ONLY_CODE=COMPILED&&!goog.DEBUG;
+goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING=!1;goog.provide=function(a){if(goog.isInModuleLoader_())throw Error("goog.provide can not be used within a goog.module.");if(!COMPILED&&goog.isProvided_(a))throw Error('Namespace "'+a+'" already declared.');goog.constructNamespace_(a)};goog.constructNamespace_=function(a,b){if(!COMPILED){delete goog.implicitNamespaces_[a];for(var c=a;(c=c.substring(0,c.lastIndexOf(".")))&&!goog.getObjectByName(c);)goog.implicitNamespaces_[c]=!0}goog.exportPath_(a,b)};
+goog.VALID_MODULE_RE_=/^[a-zA-Z_$][a-zA-Z0-9._$]*$/;
+goog.module=function(a){if(!goog.isString(a)||!a||-1==a.search(goog.VALID_MODULE_RE_))throw Error("Invalid module identifier");if(!goog.isInModuleLoader_())throw Error("Module "+a+" has been loaded incorrectly. Note, modules cannot be loaded as normal scripts. They require some kind of pre-processing step. You're likely trying to load a module via a script tag or as a part of a concatenated bundle without rewriting the module. For more info see: https://github.com/google/closure-library/wiki/goog.module:-an-ES6-module-like-alternative-to-goog.provide.");if(goog.moduleLoaderState_.moduleName)throw Error("goog.module may only be called once per module.");
+goog.moduleLoaderState_.moduleName=a;if(!COMPILED){if(goog.isProvided_(a))throw Error('Namespace "'+a+'" already declared.');delete goog.implicitNamespaces_[a]}};goog.module.get=function(a){return goog.module.getInternal_(a)};goog.module.getInternal_=function(a){if(!COMPILED)return goog.isProvided_(a)?a in goog.loadedModules_?goog.loadedModules_[a]:goog.getObjectByName(a):null};goog.moduleLoaderState_=null;goog.isInModuleLoader_=function(){return null!=goog.moduleLoaderState_};
+goog.module.declareLegacyNamespace=function(){if(!COMPILED&&!goog.isInModuleLoader_())throw Error("goog.module.declareLegacyNamespace must be called from within a goog.module");if(!COMPILED&&!goog.moduleLoaderState_.moduleName)throw Error("goog.module must be called prior to goog.module.declareLegacyNamespace.");goog.moduleLoaderState_.declareLegacyNamespace=!0};
+goog.setTestOnly=function(a){if(goog.DISALLOW_TEST_ONLY_CODE)throw a=a||"",Error("Importing test-only code into non-debug environment"+(a?": "+a:"."));};goog.forwardDeclare=function(a){};COMPILED||(goog.isProvided_=function(a){return a in goog.loadedModules_||!goog.implicitNamespaces_[a]&&goog.isDefAndNotNull(goog.getObjectByName(a))},goog.implicitNamespaces_={"goog.module":!0});
+goog.getObjectByName=function(a,b){for(var c=a.split("."),d=b||goog.global,e;e=c.shift();)if(goog.isDefAndNotNull(d[e]))d=d[e];else return null;return d};goog.globalize=function(a,b){var c=b||goog.global,d;for(d in a)c[d]=a[d]};
+goog.addDependency=function(a,b,c,d){if(goog.DEPENDENCIES_ENABLED){var e;a=a.replace(/\\/g,"/");var f=goog.dependencies_;d&&"boolean"!==typeof d||(d=d?{module:"goog"}:{});for(var g=0;e=b[g];g++)f.nameToPath[e]=a,f.loadFlags[a]=d;for(d=0;b=c[d];d++)a in f.requires||(f.requires[a]={}),f.requires[a][b]=!0}};goog.ENABLE_DEBUG_LOADER=!0;goog.logToConsole_=function(a){goog.global.console&&goog.global.console.error(a)};
+goog.require=function(a){if(!COMPILED){goog.ENABLE_DEBUG_LOADER&&goog.IS_OLD_IE_&&goog.maybeProcessDeferredDep_(a);if(goog.isProvided_(a)){if(goog.isInModuleLoader_())return goog.module.getInternal_(a)}else if(goog.ENABLE_DEBUG_LOADER){var b=goog.getPathFromDeps_(a);if(b)goog.writeScripts_(b);else throw a="goog.require could not find: "+a,goog.logToConsole_(a),Error(a);}return null}};goog.basePath="";goog.nullFunction=function(){};
+goog.abstractMethod=function(){throw Error("unimplemented abstract method");};goog.addSingletonGetter=function(a){a.getInstance=function(){if(a.instance_)return a.instance_;goog.DEBUG&&(goog.instantiatedSingletons_[goog.instantiatedSingletons_.length]=a);return a.instance_=new a}};goog.instantiatedSingletons_=[];goog.LOAD_MODULE_USING_EVAL=!0;goog.SEAL_MODULE_EXPORTS=goog.DEBUG;goog.loadedModules_={};goog.DEPENDENCIES_ENABLED=!COMPILED&&goog.ENABLE_DEBUG_LOADER;goog.TRANSPILE="detect";
+goog.TRANSPILER="transpile.js";
+goog.DEPENDENCIES_ENABLED&&(goog.dependencies_={loadFlags:{},nameToPath:{},requires:{},visited:{},written:{},deferred:{}},goog.inHtmlDocument_=function(){var a=goog.global.document;return null!=a&&"write"in a},goog.findBasePath_=function(){if(goog.isDef(goog.global.CLOSURE_BASE_PATH))goog.basePath=goog.global.CLOSURE_BASE_PATH;else if(goog.inHtmlDocument_())for(var a=goog.global.document.getElementsByTagName("SCRIPT"),b=a.length-1;0<=b;--b){var c=a[b].src,d=c.lastIndexOf("?"),d=-1==d?c.length:d;if("base.js"==
+c.substr(d-7,7)){goog.basePath=c.substr(0,d-7);break}}},goog.importScript_=function(a,b){(goog.global.CLOSURE_IMPORT_SCRIPT||goog.writeScriptTag_)(a,b)&&(goog.dependencies_.written[a]=!0)},goog.IS_OLD_IE_=!(goog.global.atob||!goog.global.document||!goog.global.document.all),goog.importProcessedScript_=function(a,b,c){goog.importScript_("",'goog.retrieveAndExec_("'+a+'", '+b+", "+c+");")},goog.queuedModules_=[],goog.wrapModule_=function(a,b){return goog.LOAD_MODULE_USING_EVAL&&goog.isDef(goog.global.JSON)?
+"goog.loadModule("+goog.global.JSON.stringify(b+"\n//# sourceURL="+a+"\n")+");":'goog.loadModule(function(exports) {"use strict";'+b+"\n;return exports});\n//# sourceURL="+a+"\n"},goog.loadQueuedModules_=function(){var a=goog.queuedModules_.length;if(0<a){var b=goog.queuedModules_;goog.queuedModules_=[];for(var c=0;c<a;c++)goog.maybeProcessDeferredPath_(b[c])}},goog.maybeProcessDeferredDep_=function(a){goog.isDeferredModule_(a)&&goog.allDepsAreAvailable_(a)&&(a=goog.getPathFromDeps_(a),goog.maybeProcessDeferredPath_(goog.basePath+
+a))},goog.isDeferredModule_=function(a){var b=(a=goog.getPathFromDeps_(a))&&goog.dependencies_.loadFlags[a]||{};return a&&("goog"==b.module||goog.needsTranspile_(b.lang))?goog.basePath+a in goog.dependencies_.deferred:!1},goog.allDepsAreAvailable_=function(a){if((a=goog.getPathFromDeps_(a))&&a in goog.dependencies_.requires)for(var b in goog.dependencies_.requires[a])if(!goog.isProvided_(b)&&!goog.isDeferredModule_(b))return!1;return!0},goog.maybeProcessDeferredPath_=function(a){if(a in goog.dependencies_.deferred){var b=
+goog.dependencies_.deferred[a];delete goog.dependencies_.deferred[a];goog.globalEval(b)}},goog.loadModuleFromUrl=function(a){goog.retrieveAndExec_(a,!0,!1)},goog.writeScriptSrcNode_=function(a){goog.global.document.write('<script type="text/javascript" src="'+a+'">\x3c/script>')},goog.appendScriptSrcNode_=function(a){var b=goog.global.document,c=b.createElement("script");c.type="text/javascript";c.src=a;c.defer=!1;c.async=!1;b.head.appendChild(c)},goog.writeScriptTag_=function(a,b){if(goog.inHtmlDocument_()){var c=
+goog.global.document;if(!goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING&&"complete"==c.readyState){if(/\bdeps.js$/.test(a))return!1;throw Error('Cannot write "'+a+'" after document load');}if(void 0===b)if(goog.IS_OLD_IE_){var d=" onreadystatechange='goog.onScriptLoad_(this, "+ ++goog.lastNonModuleScriptIndex_+")' ";c.write('<script type="text/javascript" src="'+a+'"'+d+">\x3c/script>")}else goog.ENABLE_CHROME_APP_SAFE_SCRIPT_LOADING?goog.appendScriptSrcNode_(a):goog.writeScriptSrcNode_(a);else c.write('<script type="text/javascript">'+
+b+"\x3c/script>");return!0}return!1},goog.needsTranspile_=function(a){if("always"==goog.TRANSPILE)return!0;if("never"==goog.TRANSPILE)return!1;if(!goog.transpiledLanguages_){goog.transpiledLanguages_={es5:!0,es6:!0,"es6-impl":!0};try{goog.transpiledLanguages_.es5=eval("[1,].length!=1"),eval('(()=>{"use strict";class X{constructor(){if(new.target!=String)throw 1;this.x=42}}let q=Reflect.construct(X,[],String);if(q.x!=42||!(q instanceof String))throw 1;for(const a of[2,3]){if(a==2)continue;function f(z={a}){let a=0;return z.a}{function f(){return 0;}}return f()==3}})()')&&
+(goog.transpiledLanguages_.es6=!1,goog.transpiledLanguages_["es6-impl"]=!1)}catch(b){}}return!!goog.transpiledLanguages_[a]},goog.transpiledLanguages_=null,goog.lastNonModuleScriptIndex_=0,goog.onScriptLoad_=function(a,b){"complete"==a.readyState&&goog.lastNonModuleScriptIndex_==b&&goog.loadQueuedModules_();return!0},goog.writeScripts_=function(a){function b(a){if(!(a in e.written||a in e.visited)){e.visited[a]=!0;if(a in e.requires)for(var f in e.requires[a])if(!goog.isProvided_(f))if(f in e.nameToPath)b(e.nameToPath[f]);
+else throw Error("Undefined nameToPath for "+f);a in d||(d[a]=!0,c.push(a))}}var c=[],d={},e=goog.dependencies_;b(a);for(a=0;a<c.length;a++){var f=c[a];goog.dependencies_.written[f]=!0}var g=goog.moduleLoaderState_;goog.moduleLoaderState_=null;for(a=0;a<c.length;a++)if(f=c[a]){var h=e.loadFlags[f]||{},l=goog.needsTranspile_(h.lang);"goog"==h.module||l?goog.importProcessedScript_(goog.basePath+f,"goog"==h.module,l):goog.importScript_(goog.basePath+f)}else throw goog.moduleLoaderState_=g,Error("Undefined script input");
+goog.moduleLoaderState_=g},goog.getPathFromDeps_=function(a){return a in goog.dependencies_.nameToPath?goog.dependencies_.nameToPath[a]:null},goog.findBasePath_(),goog.global.CLOSURE_NO_DEPS||goog.importScript_(goog.basePath+"deps.js"));
+goog.loadModule=function(a){var b=goog.moduleLoaderState_;try{goog.moduleLoaderState_={moduleName:void 0,declareLegacyNamespace:!1};var c;if(goog.isFunction(a))c=a.call(void 0,{});else if(goog.isString(a))c=goog.loadModuleFromSource_.call(void 0,a);else throw Error("Invalid module definition");var d=goog.moduleLoaderState_.moduleName;if(!goog.isString(d)||!d)throw Error('Invalid module name "'+d+'"');goog.moduleLoaderState_.declareLegacyNamespace?goog.constructNamespace_(d,c):goog.SEAL_MODULE_EXPORTS&&
+Object.seal&&goog.isObject(c)&&Object.seal(c);goog.loadedModules_[d]=c}finally{goog.moduleLoaderState_=b}};goog.loadModuleFromSource_=function(a){eval(a);return{}};goog.normalizePath_=function(a){a=a.split("/");for(var b=0;b<a.length;)"."==a[b]?a.splice(b,1):b&&".."==a[b]&&a[b-1]&&".."!=a[b-1]?a.splice(--b,2):b++;return a.join("/")};
+goog.loadFileSync_=function(a){if(goog.global.CLOSURE_LOAD_FILE_SYNC)return goog.global.CLOSURE_LOAD_FILE_SYNC(a);try{var b=new goog.global.XMLHttpRequest;b.open("get",a,!1);b.send();return 0==b.status||200==b.status?b.responseText:null}catch(c){return null}};
+goog.retrieveAndExec_=function(a,b,c){if(!COMPILED){var d=a;a=goog.normalizePath_(a);var e=goog.global.CLOSURE_IMPORT_SCRIPT||goog.writeScriptTag_,f=goog.loadFileSync_(a);if(null==f)throw Error('Load of "'+a+'" failed');c&&(f=goog.transpile_.call(goog.global,f,a));f=b?goog.wrapModule_(a,f):f+("\n//# sourceURL="+a);goog.IS_OLD_IE_?(goog.dependencies_.deferred[d]=f,goog.queuedModules_.push(d)):e(a,f)}};
+goog.transpile_=function(a,b){var c=goog.global.$jscomp;c||(goog.global.$jscomp=c={});var d=c.transpile;if(!d){var e=goog.basePath+goog.TRANSPILER,f=goog.loadFileSync_(e);f&&(eval(f+"\n//# sourceURL="+e),c=goog.global.$jscomp,d=c.transpile)}d||(d=c.transpile=function(a,b){goog.logToConsole_(b+" requires transpilation but no transpiler was found.");return a});return d(a,b)};
+goog.typeOf=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";
+else if("function"==b&&"undefined"==typeof a.call)return"object";return b};goog.isNull=function(a){return null===a};goog.isDefAndNotNull=function(a){return null!=a};goog.isArray=function(a){return"array"==goog.typeOf(a)};goog.isArrayLike=function(a){var b=goog.typeOf(a);return"array"==b||"object"==b&&"number"==typeof a.length};goog.isDateLike=function(a){return goog.isObject(a)&&"function"==typeof a.getFullYear};goog.isString=function(a){return"string"==typeof a};
+goog.isBoolean=function(a){return"boolean"==typeof a};goog.isNumber=function(a){return"number"==typeof a};goog.isFunction=function(a){return"function"==goog.typeOf(a)};goog.isObject=function(a){var b=typeof a;return"object"==b&&null!=a||"function"==b};goog.getUid=function(a){return a[goog.UID_PROPERTY_]||(a[goog.UID_PROPERTY_]=++goog.uidCounter_)};goog.hasUid=function(a){return!!a[goog.UID_PROPERTY_]};
+goog.removeUid=function(a){null!==a&&"removeAttribute"in a&&a.removeAttribute(goog.UID_PROPERTY_);try{delete a[goog.UID_PROPERTY_]}catch(b){}};goog.UID_PROPERTY_="closure_uid_"+(1E9*Math.random()>>>0);goog.uidCounter_=0;goog.getHashCode=goog.getUid;goog.removeHashCode=goog.removeUid;goog.cloneObject=function(a){var b=goog.typeOf(a);if("object"==b||"array"==b){if(a.clone)return a.clone();var b="array"==b?[]:{},c;for(c in a)b[c]=goog.cloneObject(a[c]);return b}return a};
+goog.bindNative_=function(a,b,c){return a.call.apply(a.bind,arguments)};goog.bindJs_=function(a,b,c){if(!a)throw Error();if(2<arguments.length){var d=Array.prototype.slice.call(arguments,2);return function(){var c=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(c,d);return a.apply(b,c)}}return function(){return a.apply(b,arguments)}};
+goog.bind=function(a,b,c){Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?goog.bind=goog.bindNative_:goog.bind=goog.bindJs_;return goog.bind.apply(null,arguments)};goog.partial=function(a,b){var c=Array.prototype.slice.call(arguments,1);return function(){var b=c.slice();b.push.apply(b,arguments);return a.apply(this,b)}};goog.mixin=function(a,b){for(var c in b)a[c]=b[c]};goog.now=goog.TRUSTED_SITE&&Date.now||function(){return+new Date};
+goog.globalEval=function(a){if(goog.global.execScript)goog.global.execScript(a,"JavaScript");else if(goog.global.eval){if(null==goog.evalWorksForGlobals_)if(goog.global.eval("var _evalTest_ = 1;"),"undefined"!=typeof goog.global._evalTest_){try{delete goog.global._evalTest_}catch(d){}goog.evalWorksForGlobals_=!0}else goog.evalWorksForGlobals_=!1;if(goog.evalWorksForGlobals_)goog.global.eval(a);else{var b=goog.global.document,c=b.createElement("SCRIPT");c.type="text/javascript";c.defer=!1;c.appendChild(b.createTextNode(a));
+b.body.appendChild(c);b.body.removeChild(c)}}else throw Error("goog.globalEval not available");};goog.evalWorksForGlobals_=null;
+goog.getCssName=function(a,b){if("."==String(a).charAt(0))throw Error('className passed in goog.getCssName must not start with ".". You passed: '+a);var c=function(a){return goog.cssNameMapping_[a]||a},d=function(a){a=a.split("-");for(var b=[],d=0;d<a.length;d++)b.push(c(a[d]));return b.join("-")},d=goog.cssNameMapping_?"BY_WHOLE"==goog.cssNameMappingStyle_?c:d:function(a){return a},d=b?a+"-"+d(b):d(a);return goog.global.CLOSURE_CSS_NAME_MAP_FN?goog.global.CLOSURE_CSS_NAME_MAP_FN(d):d};
+goog.setCssNameMapping=function(a,b){goog.cssNameMapping_=a;goog.cssNameMappingStyle_=b};!COMPILED&&goog.global.CLOSURE_CSS_NAME_MAPPING&&(goog.cssNameMapping_=goog.global.CLOSURE_CSS_NAME_MAPPING);goog.getMsg=function(a,b){b&&(a=a.replace(/\{\$([^}]+)}/g,function(a,d){return null!=b&&d in b?b[d]:a}));return a};goog.getMsgWithFallback=function(a,b){return a};goog.exportSymbol=function(a,b,c){goog.exportPath_(a,b,c)};goog.exportProperty=function(a,b,c){a[b]=c};
+goog.inherits=function(a,b){function c(){}c.prototype=b.prototype;a.superClass_=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.base=function(a,c,f){for(var d=Array(arguments.length-2),e=2;e<arguments.length;e++)d[e-2]=arguments[e];return b.prototype[c].apply(a,d)}};
+goog.base=function(a,b,c){var d=arguments.callee.caller;if(goog.STRICT_MODE_COMPATIBLE||goog.DEBUG&&!d)throw Error("arguments.caller not defined.  goog.base() cannot be used with strict mode code. See http://www.ecma-international.org/ecma-262/5.1/#sec-C");if(d.superClass_){for(var e=Array(arguments.length-1),f=1;f<arguments.length;f++)e[f-1]=arguments[f];return d.superClass_.constructor.apply(a,e)}e=Array(arguments.length-2);for(f=2;f<arguments.length;f++)e[f-2]=arguments[f];for(var f=!1,g=a.constructor;g;g=
+g.superClass_&&g.superClass_.constructor)if(g.prototype[b]===d)f=!0;else if(f)return g.prototype[b].apply(a,e);if(a[b]===d)return a.constructor.prototype[b].apply(a,e);throw Error("goog.base called from a method of one name to a method of a different name");};goog.scope=function(a){if(goog.isInModuleLoader_())throw Error("goog.scope is not supported within a goog.module.");a.call(goog.global)};COMPILED||(goog.global.COMPILED=COMPILED);
+goog.defineClass=function(a,b){var c=b.constructor,d=b.statics;c&&c!=Object.prototype.constructor||(c=function(){throw Error("cannot instantiate an interface (no constructor defined).");});c=goog.defineClass.createSealingConstructor_(c,a);a&&goog.inherits(c,a);delete b.constructor;delete b.statics;goog.defineClass.applyProperties_(c.prototype,b);null!=d&&(d instanceof Function?d(c):goog.defineClass.applyProperties_(c,d));return c};goog.defineClass.SEAL_CLASS_INSTANCES=goog.DEBUG;
+goog.defineClass.createSealingConstructor_=function(a,b){if(!goog.defineClass.SEAL_CLASS_INSTANCES)return a;var c=!goog.defineClass.isUnsealable_(b),d=function(){var b=a.apply(this,arguments)||this;b[goog.UID_PROPERTY_]=b[goog.UID_PROPERTY_];this.constructor===d&&c&&Object.seal instanceof Function&&Object.seal(b);return b};return d};goog.defineClass.isUnsealable_=function(a){return a&&a.prototype&&a.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_]};goog.defineClass.OBJECT_PROTOTYPE_FIELDS_="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");
+goog.defineClass.applyProperties_=function(a,b){for(var c in b)Object.prototype.hasOwnProperty.call(b,c)&&(a[c]=b[c]);for(var d=0;d<goog.defineClass.OBJECT_PROTOTYPE_FIELDS_.length;d++)c=goog.defineClass.OBJECT_PROTOTYPE_FIELDS_[d],Object.prototype.hasOwnProperty.call(b,c)&&(a[c]=b[c])};goog.tagUnsealableClass=function(a){!COMPILED&&goog.defineClass.SEAL_CLASS_INSTANCES&&(a.prototype[goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_]=!0)};goog.UNSEALABLE_CONSTRUCTOR_PROPERTY_="goog_defineClass_legacy_unsealable";var sre={SystemExternal:function(){}};sre.SystemExternal.locationSupported=function(){return"undefined"!=typeof location};sre.SystemExternal.url=sre.SystemExternal.locationSupported()?location.protocol+"//progressiveaccess.com/content":"https://progressiveaccess.com/content";sre.SystemExternal.jsonPath=function(){return("undefined"!==typeof process&&"undefined"!==typeof global?process.env.SRE_JSON_PATH||global.SRE_JSON_PATH||process.cwd():sre.SystemExternal.url+"/mathmaps")+"/"}();
+sre.SystemExternal.WGXpath=sre.SystemExternal.url+"/wgxpath.install.js";sre.SystemExternal.require=function(a){return"undefined"!==typeof require?require(a):null};sre.SystemExternal.documentSupported=function(){return"undefined"!=typeof document};sre.SystemExternal.xmldom=sre.SystemExternal.documentSupported()?window:sre.SystemExternal.require("xmldom");
+sre.SystemExternal.document=sre.SystemExternal.documentSupported()?document:(new sre.SystemExternal.xmldom.DOMImplementation).createDocument("","",0);sre.SystemExternal.xpath=sre.SystemExternal.documentSupported()?document:sre.SystemExternal.require("xpath");sre.SystemExternal.commander=sre.SystemExternal.documentSupported()?null:sre.SystemExternal.require("commander");sre.SystemExternal.fs=sre.SystemExternal.documentSupported()?null:sre.SystemExternal.require("fs");
+sre.SystemExternal.xm=sre.SystemExternal.documentSupported()?null:sre.SystemExternal.require("xml-mapping");sre.BrowserUtil={};sre.BrowserUtil.detectIE=function(){if(!("undefined"!==typeof window&&"ActiveXObject"in window&&"clipboardData"in window))return!1;sre.BrowserUtil.loadMapsForIE_();sre.BrowserUtil.loadWGXpath_();return!0};sre.BrowserUtil.detectEdge=function(){if(!("undefined"!==typeof window&&"MSGestureEvent"in window&&"chrome"in window&&null==window.chrome.loadTimes))return!1;document.evaluate=null;sre.BrowserUtil.loadWGXpath_(!0);return!0};sre.BrowserUtil.mapsForIE=null;
+sre.BrowserUtil.loadWGXpath_=function(a){sre.BrowserUtil.loadScript(sre.SystemExternal.WGXpath);sre.BrowserUtil.installWGXpath_(a)};sre.BrowserUtil.installWGXpath_=function(a,b){var c=b||1;"undefined"===typeof wgxpath&&10>c?setTimeout(function(){sre.BrowserUtil.installWGXpath_(a,c++)},200):10<=c||(a?wgxpath.install({document:document}):wgxpath.install(),sre.XpathUtil.xpathEvaluate=document.evaluate,sre.XpathUtil.xpathResult=XPathResult,sre.XpathUtil.createNSResolver=document.createNSResolver)};
+sre.BrowserUtil.loadMapsForIE_=function(){sre.BrowserUtil.loadScript(sre.SystemExternal.jsonPath+"mathmaps_ie.js")};sre.BrowserUtil.loadScript=function(a){var b=sre.SystemExternal.document.createElement("script");b.type="text/javascript";b.src=a;sre.SystemExternal.document.head?sre.SystemExternal.document.head.appendChild(b):sre.SystemExternal.document.body.appendChild(b)};sre.Engine=function(){this.alternativeHost=this.activeHost=null;this.allDomains=[];this.allStyles=[];this.domain="default";this.style="short";this.semantics=!1;this.mode=sre.Engine.Mode.SYNC;this.speech=sre.Engine.Speech.NONE;this.ruleSets=[];this.cache=!0;this.isEdge=this.isIE=this.strict=this.ssml=!1;this.setupTests_=[]};goog.addSingletonGetter(sre.Engine);sre.Engine.personalityProps={PITCH:"pitch",RATE:"rate",VOLUME:"volume",PAUSE:"pause"};sre.Engine.Mode={SYNC:"sync",ASYNC:"async",HTTP:"http"};
+sre.Engine.Speech={NONE:"none",SHALLOW:"shallow",DEEP:"deep"};sre.Engine.registerTest=function(a){sre.Engine.getInstance().setupTests_.push(a)};sre.Engine.isReady=function(){return sre.Engine.getInstance().setupTests_.every(function(a){return a()})};sre.Engine.prototype.setupBrowsers=function(){this.isIE=sre.BrowserUtil.detectIE();this.isEdge=sre.BrowserUtil.detectEdge()};sre.BaseUtil={};sre.BaseUtil.removeEmpty=function(a){return a.filter(function(a){return a})};sre.BaseUtil.interleaveLists=function(a,b){for(var c=[];a.length||b.length;)a.length&&c.push(a.shift()),b.length&&c.push(b.shift());return c};sre.BaseUtil.setdifference=function(a,b){return a?b?a.filter(function(a){return 0>b.indexOf(a)}):a:[]};sre.BaseUtil.union=function(a,b){return a&&b?a.concat(sre.BaseUtil.setdifference(b,a)):a||b||[]};sre.BaseUtil.makePath=function(a){return a.match("/$")?a:a+"/"};sre.Debugger=function(){this.isActive_=!1;this.outputFunction_=console.log;this.stream_=null};goog.addSingletonGetter(sre.Debugger);sre.Debugger.prototype.init=function(a){a&&this.startDebugFile_(a);this.isActive_=!0};
+sre.Debugger.prototype.startDebugFile_=function(a){this.stream_=sre.SystemExternal.fs.createWriteStream(a);this.outputFunction_=goog.bind(function(a){var b=Array.prototype.slice.call(arguments,0);this.stream_.write(b.join(" "));this.stream_.write("\n")},this);this.stream_.on("error",goog.bind(function(a){console.log("Invalid log file. Debug information sent to console.");this.outputFunction_=console.log},this));this.stream_.on("finish",function(){console.log("Finalizing debug file.")})};
+sre.Debugger.prototype.output_=function(a){this.outputFunction_.apply(console.log===this.outputFunction_?console:this.outputFunction_,["Speech Rule Engine Debugger:"].concat(a))};sre.Debugger.prototype.output=function(a){this.isActive_&&this.output_(Array.prototype.slice.call(arguments,0))};sre.Debugger.prototype.generateOutput=function(a){this.isActive_&&this.output_(a.apply(a,[]))};
+sre.Debugger.prototype.exit=function(a){this.isActive_&&this.stream_&&this.stream_.end("","",a||function(){});this.isActive_=!1};sre.XpathUtil={};sre.XpathUtil.xpathSupported=function(){return"undefined"==typeof XPathResult?!1:!0};sre.XpathUtil.currentDocument=null;sre.XpathUtil.xpathEvaluate=sre.XpathUtil.xpathSupported()?document.evaluate:sre.SystemExternal.xpath.evaluate;sre.XpathUtil.xpathResult=sre.XpathUtil.xpathSupported()?XPathResult:sre.SystemExternal.xpath.XPathResult;sre.XpathUtil.createNSResolver=sre.XpathUtil.xpathSupported()?document.createNSResolver:sre.SystemExternal.xpath.createNSResolver;
+sre.XpathUtil.nameSpaces_={xhtml:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg"};sre.XpathUtil.resolveNameSpace=function(a){return sre.XpathUtil.nameSpaces_[a]||null};sre.XpathUtil.resolver_=function(){this.lookupNamespaceURI=sre.XpathUtil.resolveNameSpace};
+sre.XpathUtil.evaluateXpath_=function(a,b,c){var d=sre.Engine.getInstance();return d.mode!==sre.Engine.Mode.HTTP||d.isIE||d.isEdge?sre.XpathUtil.xpathEvaluate(a,b,new sre.XpathUtil.resolver_,c,null):sre.XpathUtil.currentDocument.evaluate(a,b,sre.XpathUtil.resolveNameSpace,c,null)};sre.XpathUtil.evalXPath=function(a,b){try{var c=sre.XpathUtil.evaluateXpath_(a,b,sre.XpathUtil.xpathResult.ORDERED_NODE_ITERATOR_TYPE)}catch(f){return[]}for(var d=[],e=c.iterateNext();e;e=c.iterateNext())d.push(e);return d};
+sre.XpathUtil.getLeafNodes=function(a){return sre.XpathUtil.evalXPath(".//*[count(*)=0]",a)};sre.XpathUtil.evaluateBoolean=function(a,b){try{var c=sre.XpathUtil.evaluateXpath_(a,b,sre.XpathUtil.xpathResult.BOOLEAN_TYPE)}catch(d){return!1}return c.booleanValue};sre.XpathUtil.evaluateString=function(a,b){try{var c=sre.XpathUtil.evaluateXpath_(a,b,sre.XpathUtil.xpathResult.STRING_TYPE)}catch(d){return""}return c.stringValue};sre.DomUtil={};sre.DomUtil.toArray=function(a){for(var b=[],c=0;c<a.length;c++)b.push(a[c]);return b};sre.DomUtil.trimInput_=function(a){a=a.replace(/&nbsp;/g," ");return a.replace(/>\s+</g,"><").trim()};
+sre.DomUtil.parseInput=function(a,b){var c=b||Error,d=new sre.SystemExternal.xmldom.DOMParser,e=sre.DomUtil.trimInput_(a);if(!e)throw new c("Empty input!");try{var f=d.parseFromString(e,"text/xml");sre.Engine.getInstance().mode===sre.Engine.Mode.HTTP&&(sre.XpathUtil.currentDocument=f);return f.documentElement}catch(g){throw new c("Illegal input: "+g.message);}};
+sre.DomUtil.NodeType={ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3,CDATA_SECTION_NODE:4,ENTITY_REFERENCE_NODE:5,ENTITY_NODE:6,PROCESSING_INSTRUCTION_NODE:7,COMMENT_NODE:8,DOCUMENT_NODE:9,DOCUMENT_TYPE_NODE:10,DOCUMENT_FRAGMENT_NODE:11,NOTATION_NODE:12};sre.DomUtil.replaceNode=function(a,b){a.parentNode&&(a.parentNode.insertBefore(b,a),a.parentNode.removeChild(a))};sre.DomUtil.createElement=function(a){return sre.SystemExternal.document.createElement(a)};sre.DomUtil.createTextNode=function(a){return sre.SystemExternal.document.createTextNode(a)};
+sre.DomUtil.formatXml=function(a){var b=/(>)(<)(\/*)/g;a=a.replace(b,"$1\r\n$2$3");b=/(>)(.+)(<c)/g;a=a.replace(b,"$1\r\n$2\r\n$3");var c="",d="";a.split("\r\n").forEach(function(a){a.match(/.+<\/\w[^>]*>$/)?c+=d+a+"\r\n":a.match(/^<\/\w/)?d&&(d=d.slice(2),c+=d+a+"\r\n"):a.match(/^<\w[^>]*[^\/]>.*$/)?(c+=d+a+"\r\n",d+="  "):c+=d+a+"\r\n"});return c};sre.DomUtil.dataAttribute=function(a){a.match(/^data-/)&&(a=a.substr(5));return a.replace(/-([a-z])/g,function(a,c){return c.toUpperCase()})};
+sre.DomUtil.getDataAttribute=function(a,b){return a.dataset?a.dataset[sre.DomUtil.dataAttribute(b)]:a.getAttribute(b)};sre.DomUtil.querySelectorAllByAttr=function(a,b){return a.querySelectorAll?sre.DomUtil.toArray(a.querySelectorAll("["+b+"]")):sre.XpathUtil.evalXPath(".//*[@"+b+"]",a)};sre.DomUtil.querySelectorAllByAttrValue=function(a,b,c){return a.querySelectorAll?sre.DomUtil.toArray(a.querySelectorAll("["+b+'="'+c+'"]')):sre.XpathUtil.evalXPath(".//*[@"+b+'="'+c+'"]',a)};
+sre.DomUtil.querySelectorAll=function(a,b){return a.querySelectorAll?sre.DomUtil.toArray(a.querySelectorAll(b)):sre.XpathUtil.evalXPath(".//"+b,a)};sre.EnrichCase=function(){};sre.EnrichCase.prototype.getMathml=function(){};sre.AbstractEnrichCase=function(a){this.semantic=a};sre.AbstractEnrichCase.prototype.getMathml=goog.abstractMethod;sre.AbstractEnrichCase.test=goog.abstractMethod;sre.EnrichCaseFactory=function(){};sre.EnrichCaseFactory.getEmbellishedCase=function(a){return new sre.EnrichCaseFactory.embellishedCase(a)};sre.EnrichCaseFactory.cases=[];sre.EnrichCaseFactory.getCase=function(a){for(var b=0,c;c=sre.EnrichCaseFactory.cases[b];b++)if(c.test(a))return new c.constr(a);return null};sre.SemanticUtil=function(){};sre.SemanticUtil.objectsToKeys=function(a){a=Array.prototype.slice.call(arguments,0);var b=[];return b.concat.apply(b,a.map(Object.keys))};sre.SemanticUtil.objectsToValues=function(a){a=Array.prototype.slice.call(arguments,0);var b=[];a.forEach(function(a){for(var c in a)b.push(a[c])});return b};
+sre.SemanticUtil.unicodeToNumber=function(a){if(!a||2<a.length)return null;if(2==a.length){var b=a.charCodeAt(0);a=a.charCodeAt(1);return 55296<=b&&56319>=b&&!isNaN(a)?1024*(b-55296)+(a-56320)+65536:null}return a.charCodeAt(0)};sre.SemanticUtil.numberToUnicode=function(a){return 65536<=a?String.fromCharCode((a-65536)/1024+55296,(a-65536)%1024+56320):String.fromCharCode(a)};
+sre.SemanticUtil.splitUnicode=function(a){a=a.split("");for(var b=[],c=0,d;d=a[c];c++)"\ud800"<=d&&"\udbff">=d&&a[c+1]?b.push(d+a[++c]):b.push(d);return b};sre.SemanticUtil.tagName=function(a){return a.tagName.toUpperCase()};sre.SemanticUtil.LEAFTAGS=["MO","MI","MN","MTEXT","MS"];sre.SemanticUtil.IGNORETAGS="MERROR MPHANTOM MSPACE MALIGNGROUP MALIGNMARK MPRESCRIPTS ANNOTATION ANNOTATION-XML".split(" ");sre.SemanticUtil.EMPTYTAGS="MATH MROW MPADDED MACTION NONE MSTYLE SEMANTICS".split(" ");
+sre.SemanticUtil.hasMathTag=function(a){return!!a&&"MATH"===sre.SemanticUtil.tagName(a)};sre.SemanticUtil.hasIgnoreTag=function(a){return!!a&&-1!==sre.SemanticUtil.IGNORETAGS.indexOf(sre.SemanticUtil.tagName(a))};sre.SemanticUtil.hasEmptyTag=function(a){return!!a&&-1!==sre.SemanticUtil.EMPTYTAGS.indexOf(sre.SemanticUtil.tagName(a))};
+sre.SemanticUtil.purgeNodes=function(a){for(var b=[],c=0,d;d=a[c];c++){var e=sre.SemanticUtil.tagName(d);-1==sre.SemanticUtil.IGNORETAGS.indexOf(e)&&(-1!=sre.SemanticUtil.EMPTYTAGS.indexOf(e)&&0==d.childNodes.length||b.push(d))}return b};
+sre.SemanticUtil.isZeroLength=function(a){return a?-1!=="negativeveryverythinmathspace negativeverythinmathspace negativethinmathspace negativemediummathspace negativethickmathspace negativeverythickmathspace negativeveryverythickmathspace".split(" ").indexOf(a)?!0:(a=a.match(/[0-9\.]+/))?0===parseFloat(a)?!0:!1:!1:!1};sre.SemanticAttr=function(){this.generalPunctuations='!"#%&:;?@\\\u00a1\u00a7\u00b6\u00bf\u2017\u2020\u2021\u2022\u2023\u2024\u2025\u2027\u2030\u2031\u2038\u203b\u203c\u203d\u203e\u2041\u2042\u2043\u2047\u2048\u2049\u204b\u204c\u204d\u204e\u204f\u2050\u2051\u2053\u2055\u2056\u2058\u2059\u205a\u205b\u205c\u205d\u205e\ufe10\ufe13\ufe14\ufe15\ufe16\ufe30\ufe45\ufe46\ufe49\ufe4a\ufe4b\ufe4c\ufe50\ufe54\ufe55\ufe56\ufe57\ufe5f\ufe60\ufe61\ufe68\ufe6a\ufe6b\uff01\uff02\uff03\uff05\uff06\uff07\uff0a\uff0c\uff0f\uff1a\uff1b\uff1f\uff20\uff3c'.split("");
+this.invisibleComma_=sre.SemanticUtil.numberToUnicode(8291);this.commas=[",",this.invisibleComma_];this.ellipses="\u2026\u22ee\u22ef\u22f0\u22f1\ufe19".split("");this.fullStops=[".","\ufe52","\uff0e"];this.dashes="\u2012\u2013\u2014\u2015\u301c\ufe31\ufe32\ufe58".split("");this.primes="'\u2032\u2033\u2034\u2035\u2036\u2037\u2057".split("");this.openClosePairs={"(":")","[":"]","{":"}","\u2045":"\u2046","\u2329":"\u232a","\u2768":"\u2769","\u276a":"\u276b","\u276c":"\u276d","\u276e":"\u276f","\u2770":"\u2771",
+"\u2772":"\u2773","\u2774":"\u2775","\u27c5":"\u27c6","\u27e6":"\u27e7","\u27e8":"\u27e9","\u27ea":"\u27eb","\u27ec":"\u27ed","\u27ee":"\u27ef","\u2983":"\u2984","\u2985":"\u2986","\u2987":"\u2988","\u2989":"\u298a","\u298b":"\u298c","\u298d":"\u298e","\u298f":"\u2990","\u2991":"\u2992","\u2993":"\u2994","\u2995":"\u2996","\u2997":"\u2998","\u29d8":"\u29d9","\u29da":"\u29db","\u29fc":"\u29fd","\u2e22":"\u2e23","\u2e24":"\u2e25","\u2e26":"\u2e27","\u2e28":"\u2e29","\u3008":"\u3009","\u300a":"\u300b",
+"\u300c":"\u300d","\u300e":"\u300f","\u3010":"\u3011","\u3014":"\u3015","\u3016":"\u3017","\u3018":"\u3019","\u301a":"\u301b","\u301d":"\u301e","\ufd3e":"\ufd3f","\ufe17":"\ufe18","\ufe59":"\ufe5a","\ufe5b":"\ufe5c","\ufe5d":"\ufe5e","\uff08":"\uff09","\uff3b":"\uff3d","\uff5b":"\uff5d","\uff5f":"\uff60","\uff62":"\uff63","\u2308":"\u2309","\u230a":"\u230b","\u230c":"\u230d","\u230e":"\u230f","\u231c":"\u231d","\u231e":"\u231f","\u239b":"\u239e","\u239c":"\u239f","\u239d":"\u23a0","\u23a1":"\u23a4",
+"\u23a2":"\u23a5","\u23a3":"\u23a6","\u23a7":"\u23ab","\u23a8":"\u23ac","\u23a9":"\u23ad","\u23b0":"\u23b1","\u23b8":"\u23b9"};this.topBottomPairs={"\u23b4":"\u23b5","\u23dc":"\u23dd","\u23de":"\u23df","\u23e0":"\u23e1","\ufe35":"\ufe36","\ufe37":"\ufe38","\ufe39":"\ufe3a","\ufe3b":"\ufe3c","\ufe3d":"\ufe3e","\ufe3f":"\ufe40","\ufe41":"\ufe42","\ufe43":"\ufe44","\ufe47":"\ufe48"};this.leftFences=sre.SemanticUtil.objectsToKeys(this.openClosePairs);this.rightFences=sre.SemanticUtil.objectsToValues(this.openClosePairs);
+this.rightFences.push("\u301f");this.topFences=sre.SemanticUtil.objectsToKeys(this.topBottomPairs);this.bottomFences=sre.SemanticUtil.objectsToValues(this.topBottomPairs);this.neutralFences="|\u00a6\u2016\u2758\u2980\u2af4\uffe4\uff5c".split("");this.fences=this.neutralFences.concat(this.leftFences,this.rightFences,this.topFences,this.bottomFences);this.capitalLatin="ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");this.smallLatin="abcdefghijklmnopqrstuvwxyz\u0131\u0237".split("");this.capitalLatinFullWidth=
+"\uff21\uff22\uff23\uff24\uff25\uff26\uff27\uff28\uff29\uff2a\uff2b\uff2c\uff2d\uff2e\uff2f\uff30\uff31\uff32\uff33\uff34\uff35\uff36\uff37\uff38\uff39\uff3a".split("");this.smallLatinFullWidth="\uff41\uff42\uff43\uff44\uff45\uff46\uff47\uff48\uff49\uff4a\uff4b\uff4c\uff4d\uff4e\uff4f\uff50\uff51\uff52\uff53\uff54\uff55\uff56\uff57\uff58\uff59\uff5a".split("");this.capitalLatinBold="\ud835\udc00 \ud835\udc01 \ud835\udc02 \ud835\udc03 \ud835\udc04 \ud835\udc05 \ud835\udc06 \ud835\udc07 \ud835\udc08 \ud835\udc09 \ud835\udc0a \ud835\udc0b \ud835\udc0c \ud835\udc0d \ud835\udc0e \ud835\udc0f \ud835\udc10 \ud835\udc11 \ud835\udc12 \ud835\udc13 \ud835\udc14 \ud835\udc15 \ud835\udc16 \ud835\udc17 \ud835\udc18 \ud835\udc19".split(" ");
+this.smallLatinBold="\ud835\udc1a \ud835\udc1b \ud835\udc1c \ud835\udc1d \ud835\udc1e \ud835\udc1f \ud835\udc20 \ud835\udc21 \ud835\udc22 \ud835\udc23 \ud835\udc24 \ud835\udc25 \ud835\udc26 \ud835\udc27 \ud835\udc28 \ud835\udc29 \ud835\udc2a \ud835\udc2b \ud835\udc2c \ud835\udc2d \ud835\udc2e \ud835\udc2f \ud835\udc30 \ud835\udc31 \ud835\udc32 \ud835\udc33".split(" ");this.capitalLatinItalic="\ud835\udc34 \ud835\udc35 \ud835\udc36 \ud835\udc37 \ud835\udc38 \ud835\udc39 \ud835\udc3a \ud835\udc3b \ud835\udc3c \ud835\udc3d \ud835\udc3e \ud835\udc3f \ud835\udc40 \ud835\udc41 \ud835\udc42 \ud835\udc43 \ud835\udc44 \ud835\udc45 \ud835\udc46 \ud835\udc47 \ud835\udc48 \ud835\udc49 \ud835\udc4a \ud835\udc4b \ud835\udc4c \ud835\udc4d".split(" ");
+this.smallLatinItalic="\ud835\udc4e \ud835\udc4f \ud835\udc50 \ud835\udc51 \ud835\udc52 \ud835\udc53 \ud835\udc54 \u210e \ud835\udc56 \ud835\udc57 \ud835\udc58 \ud835\udc59 \ud835\udc5a \ud835\udc5b \ud835\udc5c \ud835\udc5d \ud835\udc5e \ud835\udc5f \ud835\udc60 \ud835\udc61 \ud835\udc62 \ud835\udc63 \ud835\udc64 \ud835\udc65 \ud835\udc66 \ud835\udc67 \ud835\udea4 \ud835\udea5".split(" ");this.capitalLatinScript="\ud835\udc9c \u212c \ud835\udc9e \ud835\udc9f \u2130 \u2131 \ud835\udca2 \u210b \u2110 \ud835\udca5 \ud835\udca6 \u2112 \u2133 \ud835\udca9 \ud835\udcaa \ud835\udcab \ud835\udcac \u211b \ud835\udcae \ud835\udcaf \ud835\udcb0 \ud835\udcb1 \ud835\udcb2 \ud835\udcb3 \ud835\udcb4 \ud835\udcb5 \u2118".split(" ");
+this.smallLatinScript="\ud835\udcb6 \ud835\udcb7 \ud835\udcb8 \ud835\udcb9 \u212f \ud835\udcbb \u210a \ud835\udcbd \ud835\udcbe \ud835\udcbf \ud835\udcc0 \ud835\udcc1 \ud835\udcc2 \ud835\udcc3 \u2134 \ud835\udcc5 \ud835\udcc6 \ud835\udcc7 \ud835\udcc8 \ud835\udcc9 \ud835\udcca \ud835\udccb \ud835\udccc \ud835\udccd \ud835\udcce \ud835\udccf \u2113".split(" ");this.capitalLatinBoldScript="\ud835\udcd0 \ud835\udcd1 \ud835\udcd2 \ud835\udcd3 \ud835\udcd4 \ud835\udcd5 \ud835\udcd6 \ud835\udcd7 \ud835\udcd8 \ud835\udcd9 \ud835\udcda \ud835\udcdb \ud835\udcdc \ud835\udcdd \ud835\udcde \ud835\udcdf \ud835\udce0 \ud835\udce1 \ud835\udce2 \ud835\udce3 \ud835\udce4 \ud835\udce5 \ud835\udce6 \ud835\udce7 \ud835\udce8 \ud835\udce9".split(" ");
+this.smallLatinBoldScript="\ud835\udcea \ud835\udceb \ud835\udcec \ud835\udced \ud835\udcee \ud835\udcef \ud835\udcf0 \ud835\udcf1 \ud835\udcf2 \ud835\udcf3 \ud835\udcf4 \ud835\udcf5 \ud835\udcf6 \ud835\udcf7 \ud835\udcf8 \ud835\udcf9 \ud835\udcfa \ud835\udcfb \ud835\udcfc \ud835\udcfd \ud835\udcfe \ud835\udcff \ud835\udd00 \ud835\udd01 \ud835\udd02 \ud835\udd03".split(" ");this.capitalLatinFraktur="\ud835\udd04 \ud835\udd05 \u212d \ud835\udd07 \ud835\udd08 \ud835\udd09 \ud835\udd0a \u210c \u2111 \ud835\udd0d \ud835\udd0e \ud835\udd0f \ud835\udd10 \ud835\udd11 \ud835\udd12 \ud835\udd13 \ud835\udd14 \u211c \ud835\udd16 \ud835\udd17 \ud835\udd18 \ud835\udd19 \ud835\udd1a \ud835\udd1b \ud835\udd1c \u2128".split(" ");
+this.smallLatinFraktur="\ud835\udd1e \ud835\udd1f \ud835\udd20 \ud835\udd21 \ud835\udd22 \ud835\udd23 \ud835\udd24 \ud835\udd25 \ud835\udd26 \ud835\udd27 \ud835\udd28 \ud835\udd29 \ud835\udd2a \ud835\udd2b \ud835\udd2c \ud835\udd2d \ud835\udd2e \ud835\udd2f \ud835\udd30 \ud835\udd31 \ud835\udd32 \ud835\udd33 \ud835\udd34 \ud835\udd35 \ud835\udd36 \ud835\udd37".split(" ");this.capitalLatinDoubleStruck="\ud835\udd38 \ud835\udd39 \u2102 \ud835\udd3b \ud835\udd3c \ud835\udd3d \ud835\udd3e \u210d \ud835\udd40 \ud835\udd41 \ud835\udd42 \ud835\udd43 \ud835\udd44 \u2115 \ud835\udd46 \u2119 \u211a \u211d \ud835\udd4a \ud835\udd4b \ud835\udd4c \ud835\udd4d \ud835\udd4e \ud835\udd4f \ud835\udd50 \u2124".split(" ");
+this.smallLatinDoubleStruck="\ud835\udd52 \ud835\udd53 \ud835\udd54 \ud835\udd55 \ud835\udd56 \ud835\udd57 \ud835\udd58 \ud835\udd59 \ud835\udd5a \ud835\udd5b \ud835\udd5c \ud835\udd5d \ud835\udd5e \ud835\udd5f \ud835\udd60 \ud835\udd61 \ud835\udd62 \ud835\udd63 \ud835\udd64 \ud835\udd65 \ud835\udd66 \ud835\udd67 \ud835\udd68 \ud835\udd69 \ud835\udd6a \ud835\udd6b".split(" ");this.capitalLatinBoldFraktur="\ud835\udd6c \ud835\udd6d \ud835\udd6e \ud835\udd6f \ud835\udd70 \ud835\udd71 \ud835\udd72 \ud835\udd73 \ud835\udd74 \ud835\udd75 \ud835\udd76 \ud835\udd77 \ud835\udd78 \ud835\udd79 \ud835\udd7a \ud835\udd7b \ud835\udd7c \ud835\udd7d \ud835\udd7e \ud835\udd7f \ud835\udd80 \ud835\udd81 \ud835\udd82 \ud835\udd83 \ud835\udd84 \ud835\udd85".split(" ");
+this.smallLatinBoldFraktur="\ud835\udd86 \ud835\udd87 \ud835\udd88 \ud835\udd89 \ud835\udd8a \ud835\udd8b \ud835\udd8c \ud835\udd8d \ud835\udd8e \ud835\udd8f \ud835\udd90 \ud835\udd91 \ud835\udd92 \ud835\udd93 \ud835\udd94 \ud835\udd95 \ud835\udd96 \ud835\udd97 \ud835\udd98 \ud835\udd99 \ud835\udd9a \ud835\udd9b \ud835\udd9c \ud835\udd9d \ud835\udd9e \ud835\udd9f".split(" ");this.capitalLatinSansSerif="\ud835\udda0 \ud835\udda1 \ud835\udda2 \ud835\udda3 \ud835\udda4 \ud835\udda5 \ud835\udda6 \ud835\udda7 \ud835\udda8 \ud835\udda9 \ud835\uddaa \ud835\uddab \ud835\uddac \ud835\uddad \ud835\uddae \ud835\uddaf \ud835\uddb0 \ud835\uddb1 \ud835\uddb2 \ud835\uddb3 \ud835\uddb4 \ud835\uddb5 \ud835\uddb6 \ud835\uddb7 \ud835\uddb8 \ud835\uddb9".split(" ");
+this.smallLatinSansSerif="\ud835\uddba \ud835\uddbb \ud835\uddbc \ud835\uddbd \ud835\uddbe \ud835\uddbf \ud835\uddc0 \ud835\uddc1 \ud835\uddc2 \ud835\uddc3 \ud835\uddc4 \ud835\uddc5 \ud835\uddc6 \ud835\uddc7 \ud835\uddc8 \ud835\uddc9 \ud835\uddca \ud835\uddcb \ud835\uddcc \ud835\uddcd \ud835\uddce \ud835\uddcf \ud835\uddd0 \ud835\uddd1 \ud835\uddd2 \ud835\uddd3".split(" ");this.capitalLatinSansSerifBold="\ud835\uddd4 \ud835\uddd5 \ud835\uddd6 \ud835\uddd7 \ud835\uddd8 \ud835\uddd9 \ud835\uddda \ud835\udddb \ud835\udddc \ud835\udddd \ud835\uddde \ud835\udddf \ud835\udde0 \ud835\udde1 \ud835\udde2 \ud835\udde3 \ud835\udde4 \ud835\udde5 \ud835\udde6 \ud835\udde7 \ud835\udde8 \ud835\udde9 \ud835\uddea \ud835\uddeb \ud835\uddec \ud835\udded".split(" ");
+this.smallLatinSansSerifBold="\ud835\uddee \ud835\uddef \ud835\uddf0 \ud835\uddf1 \ud835\uddf2 \ud835\uddf3 \ud835\uddf4 \ud835\uddf5 \ud835\uddf6 \ud835\uddf7 \ud835\uddf8 \ud835\uddf9 \ud835\uddfa \ud835\uddfb \ud835\uddfc \ud835\uddfd \ud835\uddfe \ud835\uddff \ud835\ude00 \ud835\ude01 \ud835\ude02 \ud835\ude03 \ud835\ude04 \ud835\ude05 \ud835\ude06 \ud835\ude07".split(" ");this.capitalLatinSansSerifItalic="\ud835\ude08 \ud835\ude09 \ud835\ude0a \ud835\ude0b \ud835\ude0c \ud835\ude0d \ud835\ude0e \ud835\ude0f \ud835\ude10 \ud835\ude11 \ud835\ude12 \ud835\ude13 \ud835\ude14 \ud835\ude15 \ud835\ude16 \ud835\ude17 \ud835\ude18 \ud835\ude19 \ud835\ude1a \ud835\ude1b \ud835\ude1c \ud835\ude1d \ud835\ude1e \ud835\ude1f \ud835\ude20 \ud835\ude21".split(" ");
+this.smallLatinSansSerifItalic="\ud835\ude22 \ud835\ude23 \ud835\ude24 \ud835\ude25 \ud835\ude26 \ud835\ude27 \ud835\ude28 \ud835\ude29 \ud835\ude2a \ud835\ude2b \ud835\ude2c \ud835\ude2d \ud835\ude2e \ud835\ude2f \ud835\ude30 \ud835\ude31 \ud835\ude32 \ud835\ude33 \ud835\ude34 \ud835\ude35 \ud835\ude36 \ud835\ude37 \ud835\ude38 \ud835\ude39 \ud835\ude3a \ud835\ude3b".split(" ");this.capitalLatinMonospace="\ud835\ude70 \ud835\ude71 \ud835\ude72 \ud835\ude73 \ud835\ude74 \ud835\ude75 \ud835\ude76 \ud835\ude77 \ud835\ude78 \ud835\ude79 \ud835\ude7a \ud835\ude7b \ud835\ude7c \ud835\ude7d \ud835\ude7e \ud835\ude7f \ud835\ude80 \ud835\ude81 \ud835\ude82 \ud835\ude83 \ud835\ude84 \ud835\ude85 \ud835\ude86 \ud835\ude87 \ud835\ude88 \ud835\ude89".split(" ");
+this.smallLatinMonospace="\ud835\ude8a \ud835\ude8b \ud835\ude8c \ud835\ude8d \ud835\ude8e \ud835\ude8f \ud835\ude90 \ud835\ude91 \ud835\ude92 \ud835\ude93 \ud835\ude94 \ud835\ude95 \ud835\ude96 \ud835\ude97 \ud835\ude98 \ud835\ude99 \ud835\ude9a \ud835\ude9b \ud835\ude9c \ud835\ude9d \ud835\ude9e \ud835\ude9f \ud835\udea0 \ud835\udea1 \ud835\udea2 \ud835\udea3".split(" ");this.latinDoubleStruckItalic=["\u2145","\u2146","\u2147","\u2148","\u2149"];this.capitalGreek="\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9".split("");
+this.smallGreek="\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9".split("");this.capitalGreekBold="\ud835\udea8 \ud835\udea9 \ud835\udeaa \ud835\udeab \ud835\udeac \ud835\udead \ud835\udeae \ud835\udeaf \ud835\udeb0 \ud835\udeb1 \ud835\udeb2 \ud835\udeb3 \ud835\udeb4 \ud835\udeb5 \ud835\udeb6 \ud835\udeb7 \ud835\udeb8 \ud835\udeba \ud835\udebb \ud835\udebc \ud835\udebd \ud835\udebe \ud835\udebf \ud835\udec0".split(" ");
+this.smallGreekBold="\ud835\udec2 \ud835\udec3 \ud835\udec4 \ud835\udec5 \ud835\udec6 \ud835\udec7 \ud835\udec8 \ud835\udec9 \ud835\udeca \ud835\udecb \ud835\udecc \ud835\udecd \ud835\udece \ud835\udecf \ud835\uded0 \ud835\uded1 \ud835\uded2 \ud835\uded3 \ud835\uded4 \ud835\uded5 \ud835\uded6 \ud835\uded7 \ud835\uded8 \ud835\uded9 \ud835\udeda".split(" ");this.capitalGreekItalic="\ud835\udee2 \ud835\udee3 \ud835\udee4 \ud835\udee5 \ud835\udee6 \ud835\udee7 \ud835\udee8 \ud835\udee9 \ud835\udeea \ud835\udeeb \ud835\udeec \ud835\udeed \ud835\udeee \ud835\udeef \ud835\udef0 \ud835\udef1 \ud835\udef2 \ud835\udef4 \ud835\udef5 \ud835\udef6 \ud835\udef7 \ud835\udef8 \ud835\udef9 \ud835\udefa".split(" ");
+this.smallGreekItalic="\ud835\udefc \ud835\udefd \ud835\udefe \ud835\udeff \ud835\udf00 \ud835\udf01 \ud835\udf02 \ud835\udf03 \ud835\udf04 \ud835\udf05 \ud835\udf06 \ud835\udf07 \ud835\udf08 \ud835\udf09 \ud835\udf0a \ud835\udf0b \ud835\udf0c \ud835\udf0d \ud835\udf0e \ud835\udf0f \ud835\udf10 \ud835\udf11 \ud835\udf12 \ud835\udf13 \ud835\udf14".split(" ");this.capitalGreekSansSerifBold="\ud835\udf56 \ud835\udf57 \ud835\udf58 \ud835\udf59 \ud835\udf5a \ud835\udf5b \ud835\udf5c \ud835\udf5d \ud835\udf5e \ud835\udf5f \ud835\udf60 \ud835\udf61 \ud835\udf62 \ud835\udf63 \ud835\udf64 \ud835\udf65 \ud835\udf66 \ud835\udf68 \ud835\udf69 \ud835\udf6a \ud835\udf6b \ud835\udf6c \ud835\udf6d \ud835\udf6e".split(" ");
+this.smallGreekSansSerifBold="\ud835\udf70 \ud835\udf71 \ud835\udf72 \ud835\udf73 \ud835\udf74 \ud835\udf75 \ud835\udf76 \ud835\udf77 \ud835\udf78 \ud835\udf79 \ud835\udf7a \ud835\udf7b \ud835\udf7c \ud835\udf7d \ud835\udf7e \ud835\udf7f \ud835\udf80 \ud835\udf81 \ud835\udf82 \ud835\udf83 \ud835\udf84 \ud835\udf85 \ud835\udf86 \ud835\udf87 \ud835\udf88".split(" ");this.greekDoubleStruck=["\u213c","\u213d","\u213e","\u213f"];this.hebrewLetters=["\u2135","\u2136","\u2137","\u2138"];this.allLetters=
+this.capitalLatin.concat(this.smallLatin,this.capitalLatinFullWidth,this.smallLatinFullWidth,this.capitalLatinBold,this.smallLatinBold,this.capitalLatinItalic,this.smallLatinItalic,this.capitalLatinScript,this.smallLatinScript,this.capitalLatinBoldScript,this.smallLatinBoldScript,this.capitalLatinFraktur,this.smallLatinFraktur,this.capitalLatinDoubleStruck,this.smallLatinDoubleStruck,this.capitalLatinBoldFraktur,this.smallLatinBoldFraktur,this.capitalLatinSansSerif,this.smallLatinSansSerif,this.capitalLatinSansSerifBold,
+this.smallLatinSansSerifBold,this.capitalLatinSansSerifItalic,this.smallLatinSansSerifItalic,this.capitalLatinMonospace,this.smallLatinMonospace,this.latinDoubleStruckItalic,this.capitalGreek,this.smallGreek,this.capitalGreekBold,this.smallGreekBold,this.capitalGreekItalic,this.smallGreekItalic,this.capitalGreekSansSerifBold,this.smallGreekSansSerifBold,this.greekDoubleStruck,this.hebrewLetters);this.additions="+\u00b1\u2213\u2214\u2227\u2228\u2229\u222a\u228c\u2293\u2294\u229d\u229e\u22a4\u22a5\u22ba\u22bb\u22bc\u22c4\u22ce\u22cf\u22d2\u22d3\u25b3\u25b7\u25bd\u25c1\u2a5e\u2295".split("");
+this.invisiblePlus_=sre.SemanticUtil.numberToUnicode(8292);this.additions.push(this.invisiblePlus_);this.multiplications="\u2020\u2021\u2210\u2217\u2218\u2219\u2240\u229a\u229b\u22a0\u22a1\u22c5\u22c6\u22c7\u22c9\u22ca\u22cb\u22cc\u25cb\u00b7*".split("");this.invisibleTimes_=sre.SemanticUtil.numberToUnicode(8290);this.multiplications.push(this.invisibleTimes_);this.subtractions="-\u2052\u207b\u208b\u2212\u2216\u2238\u2242\u2296\u229f\u2796\u2a29\u2a2a\u2a2b\u2a2c\u2a3a\u2a41\u2a6c\ufe63\uff0d\u2010\u2011".split("");
+this.divisions="/\u00f7\u2044\u2215\u2298\u27cc\u29bc\u2a38".split("");this.functionApplication_=sre.SemanticUtil.numberToUnicode(8289);this.equalities="=~\u207c\u208c\u223c\u223d\u2243\u2245\u2248\u224a\u224b\u224c\u224d\u224e\u2251\u2252\u2253\u2254\u2255\u2256\u2257\u2258\u2259\u225a\u225b\u225c\u225d\u225e\u225f\u2261\u2263\u29e4\u2a66\u2a6e\u2a6f\u2a70\u2a71\u2a72\u2a73\u2a74\u2a75\u2a76\u2a77\u2a78\u22d5\u2a6d\u2a6a\u2a6b\u2a6c\ufe66\uff1d".split("");this.inequalities="<>\u2241\u2242\u2244\u2246\u2247\u2249\u224f\u2250\u2260\u2262\u2264\u2265\u2266\u2267\u2268\u2269\u226a\u226b\u226c\u226d\u226e\u226f\u2270\u2271\u2272\u2273\u2274\u2275\u2276\u2277\u2278\u2279\u227a\u227b\u227c\u227d\u227e\u227f\u2280\u2281\u22d6\u22d7\u22d8\u22d9\u22da\u22db\u22dc\u22dd\u22de\u22df\u22e0\u22e1\u22e2\u22e3\u22e4\u22e5\u22e6\u22e7\u22e8\u22e9\u2a79\u2a7a\u2a7b\u2a7c\u2a7d\u2a7e\u2a7f\u2a80\u2a81\u2a82\u2a83\u2a84\u2a85\u2a86\u2a87\u2a88\u2a89\u2a8a\u2a8b\u2a8c\u2a8d\u2a8e\u2a8f\u2a90\u2a91\u2a92\u2a93\u2a94\u2a95\u2a96\u2a97\u2a98\u2a99\u2a9a\u2a9b\u2a9c\u2a9d\u2a9e\u2a9f\u2aa0\u2aa1\u2aa2\u2aa3\u2aa4\u2aa5\u2aa6\u2aa7\u2aa8\u2aa9\u2aaa\u2aab\u2aac\u2aad\u2aae\u2aaf\u2ab0\u2ab1\u2ab2\u2ab3\u2ab4\u2ab5\u2ab6\u2ab7\u2ab8\u2ab9\u2aba\u2abb\u2abc\u2af7\u2af8\u2af9\u2afa\u29c0\u29c1\ufe64\ufe65\uff1c\uff1e".split("");
+this.relations=[];this.arrows="\u2190\u2191\u2192\u2193\u2194\u2195\u2196\u2197\u2198\u2199\u219a\u219b\u219c\u219d\u219e\u219f\u21a0\u21a1\u21a2\u21a3\u21a4\u21a5\u21a6\u21a7\u21a8\u21a9\u21aa\u21ab\u21ac\u21ad\u21ae\u21af\u21b0\u21b1\u21b2\u21b3\u21b4\u21b5\u21b6\u21b7\u21b8\u21b9\u21ba\u21bb\u21c4\u21c5\u21c6\u21c7\u21c8\u21c9\u21ca\u21cd\u21ce\u21cf\u21d0\u21d1\u21d2\u21d3\u21d4\u21d5\u21d6\u21d7\u21d8\u21d9\u21da\u21db\u21dc\u21dd\u21de\u21df\u21e0\u21e1\u21e2\u21e3\u21e4\u21e5\u21e6\u21e7\u21e8\u21e9\u21ea\u21eb\u21ec\u21ed\u21ee\u21ef\u21f0\u21f1\u21f2\u21f3\u21f4\u21f5\u21f6\u21f7\u21f8\u21f9\u21fa\u21fb\u21fc\u21fd\u21fe\u21ff\u2301\u2303\u2304\u2324\u238b\u2794\u2798\u2799\u279a\u279b\u279c\u279d\u279e\u279f\u27a0\u27a1\u27a2\u27a3\u27a4\u27a5\u27a6\u27a7\u27a8\u27a9\u27aa\u27ab\u27ac\u27ad\u27ae\u27af\u27b1\u27b2\u27b3\u27b4\u27b5\u27b6\u27b7\u27b8\u27b9\u27ba\u27bb\u27bc\u27bd\u27be\u27f0\u27f1\u27f2\u27f3\u27f4\u27f5\u27f6\u27f7\u27f8\u27f9\u27fa\u27fb\u27fc\u27fd\u27fe\u27ff\u2900\u2901\u2902\u2903\u2904\u2905\u2906\u2907\u2908\u2909\u290a\u290b\u290c\u290d\u290e\u290f\u2910\u2911\u2912\u2913\u2914\u2915\u2916\u2917\u2918\u2919\u291a\u291b\u291c\u291d\u291e\u291f\u2920\u2921\u2922\u2923\u2924\u2925\u2926\u2927\u2928\u2929\u292a\u292d\u292e\u292f\u2930\u2931\u2932\u2933\u2934\u2935\u2936\u2937\u2938\u2939\u293a\u293b\u293c\u293d\u293e\u293f\u2940\u2941\u2942\u2943\u2944\u2945\u2946\u2947\u2948\u2949\u2970\u2971\u2972\u2973\u2974\u2975\u2976\u2977\u2978\u2979\u297a\u297b\u29b3\u29b4\u29bd\u29ea\u29ec\u29ed\u2a17\u2b00\u2b01\u2b02\u2b03\u2b04\u2b05\u2b06\u2b07\u2b08\u2b09\u2b0a\u2b0b\u2b0c\u2b0d\u2b0e\u2b0f\u2b10\u2b11\u2b30\u2b31\u2b32\u2b33\u2b34\u2b35\u2b36\u2b37\u2b38\u2b39\u2b3a\u2b3b\u2b3c\u2b3d\u2b3e\u2b3f\u2b40\u2b41\u2b42\u2b43\u2b44\u2b45\u2b46\u2b47\u2b48\u2b49\u2b4a\u2b4b\u2b4c\uffe9\uffea\uffeb\uffec\u21bc\u21bd\u21be\u21bf\u21c0\u21c1\u21c2\u21c3\u21cb\u21cc\u294a\u294b\u294c\u294d\u294e\u294f\u2950\u2951\u2952\u2953\u2954\u2955\u2956\u2957\u2958\u2959\u295a\u295b\u295c\u295d\u295e\u295f\u2960\u2961\u2962\u2963\u2964\u2965\u2966\u2967\u2968\u2969\u296a\u296b\u296c\u296d\u296e\u296f\u297c\u297d\u297e\u297f".split("");
+this.sumOps="\u2140\u220f\u2210\u2211\u22c0\u22c1\u22c2\u22c3\u2a00\u2a01\u2a02\u2a03\u2a04\u2a05\u2a06\u2a07\u2a08\u2a09\u2a0a\u2a0b\u2afc\u2aff".split("");this.intOps="\u222b\u222c\u222d\u222e\u222f\u2230\u2231\u2232\u2233\u2a0c\u2a0d\u2a0e\u2a0f\u2a10\u2a11\u2a12\u2a13\u2a14\u2a15\u2a16\u2a17\u2a18\u2a19\u2a1a\u2a1b\u2a1c".split("");this.prefixOps=["\u2200","\u2203"];this.operatorBits="\u2320\u2321\u23b6\u23aa\u23ae\u23af\u23b2\u23b3\u23b7".split("");this.digitsNormal="0123456789".split("");this.digitsFullWidth=
+"\uff10\uff11\uff12\uff13\uff14\uff15\uff16\uff17\uff18\uff19".split("");this.digitsBold="\ud835\udfce \ud835\udfcf \ud835\udfd0 \ud835\udfd1 \ud835\udfd2 \ud835\udfd3 \ud835\udfd4 \ud835\udfd5 \ud835\udfd6 \ud835\udfd7".split(" ");this.digitsDoubleStruck="\ud835\udfd8 \ud835\udfd9 \ud835\udfda \ud835\udfdb \ud835\udfdc \ud835\udfdd \ud835\udfde \ud835\udfdf \ud835\udfe0 \ud835\udfe1".split(" ");this.digitsSansSerif="\ud835\udfe2 \ud835\udfe3 \ud835\udfe4 \ud835\udfe5 \ud835\udfe6 \ud835\udfe7 \ud835\udfe8 \ud835\udfe9 \ud835\udfea \ud835\udfeb".split(" ");
+this.digitsSansSerifBold="\ud835\udfec \ud835\udfed \ud835\udfee \ud835\udfef \ud835\udff0 \ud835\udff1 \ud835\udff2 \ud835\udff3 \ud835\udff4 \ud835\udff5".split(" ");this.digitsMonospace="\ud835\udff6 \ud835\udff7 \ud835\udff8 \ud835\udff9 \ud835\udffa \ud835\udffb \ud835\udffc \ud835\udffd \ud835\udffe \ud835\udfff".split(" ");this.digitsSuperscript="\u00b2\u00b3\u00b9\u2070\u2074\u2075\u2076\u2077\u2078\u2079".split("");this.digitsSubscript="\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089".split("");
+this.fractions="\u00bc\u00bd\u00be\u2150\u2151\u2152\u2153\u2154\u2155\u2156\u2157\u2158\u2159\u215a\u215b\u215c\u215d\u215e\u215f\u2189".split("");this.enclosedNumbers="\u2460\u2461\u2462\u2463\u2464\u2465\u2466\u2467\u2468\u2469\u246a\u246b\u246c\u246d\u246e\u246f\u2470\u2471\u2472\u2473\u24ea\u24eb\u24ec\u24ed\u24ee\u24ef\u24f0\u24f1\u24f2\u24f3\u24f4\u24f5\u24f6\u24f7\u24f8\u24f9\u24fa\u24fb\u24fc\u24fd\u24fe\u24ff\u2776\u2777\u2778\u2779\u277a\u277b\u277c\u277d\u277e\u277f\u2780\u2781\u2782\u2783\u2784\u2785\u2786\u2787\u2788\u2789\u278a\u278b\u278c\u278d\u278e\u278f\u2790\u2791\u2792\u2793\u3248\u3249\u324a\u324b\u324c\u324d\u324e\u324f\u3251\u3252\u3253\u3254\u3255\u3256\u3257\u3258\u3259\u325a\u325b\u325c\u325d\u325e\u325f\u32b1\u32b2\u32b3\u32b4\u32b5\u32b6\u32b7\u32b8\u32b9\u32ba\u32bb\u32bc\u32bd\u32be\u32bf".split("");
+this.fencedNumbers="\u2474\u2475\u2476\u2477\u2478\u2479\u247a\u247b\u247c\u247d\u247e\u247f\u2480\u2481\u2482\u2483\u2484\u2485\u2486\u2487".split("");this.punctuatedNumbers="\u2488 \u2489 \u248a \u248b \u248c \u248d \u248e \u248f \u2490 \u2491 \u2492 \u2493 \u2494 \u2495 \u2496 \u2497 \u2498 \u2499 \u249a \u249b \ud83c\udd00 \ud83c\udd01 \ud83c\udd02 \ud83c\udd03 \ud83c\udd04 \ud83c\udd05 \ud83c\udd06 \ud83c\udd07 \ud83c\udd08 \ud83c\udd09 \ud83c\udd0a".split(" ");this.digits=this.digitsNormal.concat(this.digitsFullWidth,
+this.digitsBold,this.digitsDoubleStruck,this.digitsSansSerif,this.digitsSansSerifBold,this.digitsMonospace);this.numbers=this.fractions.concat(this.digitsSuperscript,this.digitsSubscript,this.enclosedNumbers,this.fencedNumbers,this.punctuatedNumbers);this.allNumbers=this.digits.concat(this.numbers);this.trigonometricFunctions="cos cot csc sec sin tan arccos arccot arccsc arcsec arcsin arctan".split(" ");this.hyperbolicFunctions="cosh coth csch sech sinh tanh arcosh arcoth arcsch arsech arsinh artanh arccosh arccoth arccsch arcsech arcsinh arctanh".split(" ");
+this.algebraicFunctions="deg det dim hom ker Tr tr".split(" ");this.elementaryFunctions="log ln lg exp expt gcd gcd arg im re Pr".split(" ");this.prefixFunctions=this.trigonometricFunctions.concat(this.hyperbolicFunctions,this.algebraicFunctions,this.elementaryFunctions);this.limitFunctions="inf lim liminf limsup max min sup injlim projlim".split(" ");this.infixFunctions=["mod","rem"];this.symbolSetToSemantic_=[{set:this.generalPunctuations,type:sre.SemanticAttr.Type.PUNCTUATION,role:sre.SemanticAttr.Role.UNKNOWN},
+{set:this.commas,type:sre.SemanticAttr.Type.PUNCTUATION,role:sre.SemanticAttr.Role.COMMA},{set:this.ellipses,type:sre.SemanticAttr.Type.PUNCTUATION,role:sre.SemanticAttr.Role.ELLIPSIS},{set:this.fullStops,type:sre.SemanticAttr.Type.PUNCTUATION,role:sre.SemanticAttr.Role.FULLSTOP},{set:this.dashes,type:sre.SemanticAttr.Type.PUNCTUATION,role:sre.SemanticAttr.Role.DASH},{set:this.primes,type:sre.SemanticAttr.Type.PUNCTUATION,role:sre.SemanticAttr.Role.PRIME},{set:this.leftFences,type:sre.SemanticAttr.Type.FENCE,
+role:sre.SemanticAttr.Role.OPEN},{set:this.rightFences,type:sre.SemanticAttr.Type.FENCE,role:sre.SemanticAttr.Role.CLOSE},{set:this.topFences,type:sre.SemanticAttr.Type.FENCE,role:sre.SemanticAttr.Role.TOP},{set:this.bottomFences,type:sre.SemanticAttr.Type.FENCE,role:sre.SemanticAttr.Role.BOTTOM},{set:this.neutralFences,type:sre.SemanticAttr.Type.FENCE,role:sre.SemanticAttr.Role.NEUTRAL},{set:this.smallLatin,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.NORMAL},
+{set:this.capitalLatin,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.NORMAL},{set:this.smallLatinFullWidth,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.NORMAL},{set:this.capitalLatinFullWidth,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.NORMAL},{set:this.smallLatinBold,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,
+font:sre.SemanticAttr.Font.BOLD},{set:this.capitalLatinBold,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.BOLD},{set:this.smallLatinItalic,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.ITALIC},{set:this.capitalLatinItalic,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.ITALIC},{set:this.smallLatinScript,type:sre.SemanticAttr.Type.IDENTIFIER,
+role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.SCRIPT},{set:this.capitalLatinScript,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.SCRIPT},{set:this.smallLatinBoldScript,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.BOLDSCRIPT},{set:this.capitalLatinBoldScript,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.BOLDSCRIPT},
+{set:this.smallLatinFraktur,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.FRAKTUR},{set:this.capitalLatinFraktur,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.FRAKTUR},{set:this.smallLatinDoubleStruck,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.DOUBLESTRUCK},{set:this.capitalLatinDoubleStruck,type:sre.SemanticAttr.Type.IDENTIFIER,
+role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.DOUBLESTRUCK},{set:this.smallLatinBoldFraktur,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.BOLDFRAKTUR},{set:this.capitalLatinBoldFraktur,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.BOLDFRAKTUR},{set:this.smallLatinSansSerif,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.SANSSERIF},
+{set:this.capitalLatinSansSerif,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.SANSSERIF},{set:this.smallLatinSansSerifBold,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.SANSSERIFBOLD},{set:this.capitalLatinSansSerifBold,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.SANSSERIFBOLD},{set:this.smallLatinSansSerifItalic,type:sre.SemanticAttr.Type.IDENTIFIER,
+role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.SANSSERIFITALIC},{set:this.capitalLatinSansSerifItalic,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.SANSSERIFITALIC},{set:this.smallLatinMonospace,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.MONOSPACE},{set:this.capitalLatinMonospace,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.MONOSPACE},
+{set:this.latinDoubleStruckItalic,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.LATINLETTER,font:sre.SemanticAttr.Font.DOUBLESTRUCKITALIC},{set:this.smallGreek,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.GREEKLETTER,font:sre.SemanticAttr.Font.NORMAL},{set:this.capitalGreek,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.GREEKLETTER,font:sre.SemanticAttr.Font.NORMAL},{set:this.smallGreekBold,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.GREEKLETTER,
+font:sre.SemanticAttr.Font.BOLD},{set:this.capitalGreekBold,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.GREEKLETTER,font:sre.SemanticAttr.Font.BOLD},{set:this.smallGreekItalic,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.GREEKLETTER,font:sre.SemanticAttr.Font.ITALIC},{set:this.capitalGreekItalic,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.GREEKLETTER,font:sre.SemanticAttr.Font.ITALIC},{set:this.smallGreekSansSerifBold,type:sre.SemanticAttr.Type.IDENTIFIER,
+role:sre.SemanticAttr.Role.GREEKLETTER,font:sre.SemanticAttr.Font.SANSSERIFBOLD},{set:this.capitalGreekSansSerifBold,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.GREEKLETTER,font:sre.SemanticAttr.Font.SANSSERIFBOLD},{set:this.greekDoubleStruck,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.GREEKLETTER,font:sre.SemanticAttr.Font.DOUBLESTRUCK},{set:this.hebrewLetters,type:sre.SemanticAttr.Type.IDENTIFIER,role:sre.SemanticAttr.Role.OTHERLETTER,font:sre.SemanticAttr.Font.NORMAL},
+{set:this.digitsNormal,type:sre.SemanticAttr.Type.NUMBER,role:sre.SemanticAttr.Role.INTEGER,font:sre.SemanticAttr.Font.NORMAL},{set:this.digitsFullWidth,type:sre.SemanticAttr.Type.NUMBER,role:sre.SemanticAttr.Role.INTEGER,font:sre.SemanticAttr.Font.NORMAL},{set:this.digitsBold,type:sre.SemanticAttr.Type.NUMBER,role:sre.SemanticAttr.Role.INTEGER,font:sre.SemanticAttr.Font.BOLD},{set:this.digitsDoubleStruck,type:sre.SemanticAttr.Type.NUMBER,role:sre.SemanticAttr.Role.INTEGER,font:sre.SemanticAttr.Font.DOUBLESTRUCK},
+{set:this.digitsSansSerif,type:sre.SemanticAttr.Type.NUMBER,role:sre.SemanticAttr.Role.INTEGER,font:sre.SemanticAttr.Font.SANSSERIF},{set:this.digitsSansSerifBold,type:sre.SemanticAttr.Type.NUMBER,role:sre.SemanticAttr.Role.INTEGER,font:sre.SemanticAttr.Font.SANSSERIFBOLD},{set:this.digitsMonospace,type:sre.SemanticAttr.Type.NUMBER,role:sre.SemanticAttr.Role.INTEGER,font:sre.SemanticAttr.Font.MONOSPACE},{set:this.numbers,type:sre.SemanticAttr.Type.NUMBER,role:sre.SemanticAttr.Role.FLOAT},{set:this.additions,
+type:sre.SemanticAttr.Type.OPERATOR,role:sre.SemanticAttr.Role.ADDITION},{set:this.multiplications,type:sre.SemanticAttr.Type.OPERATOR,role:sre.SemanticAttr.Role.MULTIPLICATION},{set:this.subtractions,type:sre.SemanticAttr.Type.OPERATOR,role:sre.SemanticAttr.Role.SUBTRACTION},{set:this.divisions,type:sre.SemanticAttr.Type.OPERATOR,role:sre.SemanticAttr.Role.DIVISION},{set:this.prefixOps,type:sre.SemanticAttr.Type.PREFIXOP,role:sre.SemanticAttr.Role.PREFIXFUNC},{set:this.equalities,type:sre.SemanticAttr.Type.RELATION,
+role:sre.SemanticAttr.Role.EQUALITY},{set:this.inequalities,type:sre.SemanticAttr.Type.RELATION,role:sre.SemanticAttr.Role.INEQUALITY},{set:this.relations,type:sre.SemanticAttr.Type.RELATION,role:sre.SemanticAttr.Role.UNKNOWN},{set:this.arrows,type:sre.SemanticAttr.Type.RELATION,role:sre.SemanticAttr.Role.ARROW},{set:this.sumOps,type:sre.SemanticAttr.Type.LARGEOP,role:sre.SemanticAttr.Role.SUM},{set:this.intOps,type:sre.SemanticAttr.Type.LARGEOP,role:sre.SemanticAttr.Role.INTEGRAL},{set:this.limitFunctions,
+type:sre.SemanticAttr.Type.FUNCTION,role:sre.SemanticAttr.Role.LIMFUNC},{set:this.prefixFunctions,type:sre.SemanticAttr.Type.FUNCTION,role:sre.SemanticAttr.Role.PREFIXFUNC},{set:this.infixFunctions,type:sre.SemanticAttr.Type.OPERATOR,role:sre.SemanticAttr.Role.MULTIPLICATION}];this.meaning_=this.initMeaning_()};goog.addSingletonGetter(sre.SemanticAttr);
+sre.SemanticAttr.Type={PUNCTUATION:"punctuation",FENCE:"fence",NUMBER:"number",IDENTIFIER:"identifier",TEXT:"text",OPERATOR:"operator",RELATION:"relation",LARGEOP:"largeop",FUNCTION:"function",ACCENT:"accent",FENCED:"fenced",FRACTION:"fraction",PUNCTUATED:"punctuated",RELSEQ:"relseq",MULTIREL:"multirel",INFIXOP:"infixop",PREFIXOP:"prefixop",POSTFIXOP:"postfixop",APPL:"appl",INTEGRAL:"integral",BIGOP:"bigop",SQRT:"sqrt",ROOT:"root",LIMUPPER:"limupper",LIMLOWER:"limlower",LIMBOTH:"limboth",SUBSCRIPT:"subscript",
+SUPERSCRIPT:"superscript",UNDERSCORE:"underscore",OVERSCORE:"overscore",TENSOR:"tensor",TABLE:"table",MULTILINE:"multiline",MATRIX:"matrix",VECTOR:"vector",CASES:"cases",ROW:"row",LINE:"line",CELL:"cell",ENCLOSE:"enclose",UNKNOWN:"unknown",EMPTY:"empty"};
+sre.SemanticAttr.Role={COMMA:"comma",ELLIPSIS:"ellipsis",FULLSTOP:"fullstop",DASH:"dash",PRIME:"prime",VBAR:"vbar",OPENFENCE:"openfence",CLOSEFENCE:"closefence",APPLICATION:"application",DUMMY:"dummy",UNIT:"unit",OPEN:"open",CLOSE:"close",TOP:"top",BOTTOM:"bottom",NEUTRAL:"neutral",LATINLETTER:"latinletter",GREEKLETTER:"greekletter",OTHERLETTER:"otherletter",INTEGER:"integer",FLOAT:"float",OTHERNUMBER:"othernumber",MIXED:"mixed",MULTIACCENT:"multiaccent",OVERACCENT:"overaccent",UNDERACCENT:"underaccent",
+UNDEROVER:"underover",SUBSUP:"subsup",LEFTSUB:"leftsub",LEFTSUPER:"leftsuper",RIGHTSUB:"rightsub",RIGHTSUPER:"rightsuper",LEFTRIGHT:"leftright",ABOVEBELOW:"abovebelow",STRING:"string",SEQUENCE:"sequence",ENDPUNCT:"endpunct",STARTPUNCT:"startpunct",TEXT:"text",NEGATIVE:"negative",NEGATION:"negation",MULTIOP:"multiop",LIMFUNC:"limit function",INFIXFUNC:"infix function",PREFIXFUNC:"prefix function",POSTFIXFUNC:"postfix function",SIMPLEFUNC:"simple function",SUM:"sum",INTEGRAL:"integral",ADDITION:"addition",
+MULTIPLICATION:"multiplication",SUBTRACTION:"subtraction",IMPLICIT:"implicit",DIVISION:"division",VULGAR:"vulgar",EQUALITY:"equality",INEQUALITY:"inequality",ELEMENT:"element",BINREL:"binrel",ARROW:"arrow",DETERMINANT:"determinant",ROWVECTOR:"rowvector",BINOMIAL:"binomial",SQUAREMATRIX:"squarematrix",MULTILINE:"multiline",MATRIX:"matrix",VECTOR:"vector",CASES:"cases",TABLE:"table",UNKNOWN:"unknown",PROTECTED:"protected"};
+sre.SemanticAttr.Font={BOLD:"bold",BOLDFRAKTUR:"bold-fraktur",BOLDITALIC:"bold-italic",BOLDSCRIPT:"bold-script",DOUBLESTRUCK:"double-struck",DOUBLESTRUCKITALIC:"double-struck-italic",FRAKTUR:"fraktur",ITALIC:"italic",MONOSPACE:"monospace",NORMAL:"normal",SCRIPT:"script",SANSSERIF:"sans-serif",SANSSERIFITALIC:"sans-serif-italic",SANSSERIFBOLD:"sans-serif-bold",SANSSERIFBOLDITALIC:"sans-serif-bold-italic",UNKNOWN:"unknown"};sre.SemanticAttr.prototype.lookupType=function(a){return sre.SemanticAttr.Type.UNKNOWN};
+sre.SemanticAttr.prototype.lookupRole=function(a){return sre.SemanticAttr.Role.UNKNOWN};sre.SemanticAttr.lookupMeaning=function(a){return sre.SemanticAttr.getInstance().lookupMeaning_(a)};sre.SemanticAttr.invisibleTimes=function(){return sre.SemanticAttr.getInstance().invisibleTimes_};sre.SemanticAttr.invisibleComma=function(){return sre.SemanticAttr.getInstance().invisibleComma_};sre.SemanticAttr.functionApplication=function(){return sre.SemanticAttr.getInstance().functionApplication_};
+sre.SemanticAttr.isMatchingFenceRole=function(a,b){return a==sre.SemanticAttr.Role.OPEN&&b==sre.SemanticAttr.Role.CLOSE||a==sre.SemanticAttr.Role.NEUTRAL&&b==sre.SemanticAttr.Role.NEUTRAL||a==sre.SemanticAttr.Role.TOP&&b==sre.SemanticAttr.Role.BOTTOM};sre.SemanticAttr.isMatchingFence=function(a,b){return sre.SemanticAttr.getInstance().isMatchingFence_(a,b)};sre.SemanticAttr.isOpeningFence=function(a){return a==sre.SemanticAttr.Role.OPEN||a==sre.SemanticAttr.Role.NEUTRAL};
+sre.SemanticAttr.isClosingFence=function(a){return a==sre.SemanticAttr.Role.CLOSE||a==sre.SemanticAttr.Role.NEUTRAL};sre.SemanticAttr.isEmbellishedType=function(a){return a===sre.SemanticAttr.Type.OPERATOR||a===sre.SemanticAttr.Type.RELATION||a===sre.SemanticAttr.Type.FENCE||a===sre.SemanticAttr.Type.PUNCTUATION};sre.SemanticAttr.isCharacterD=function(a){return-1!="d \u2146 \uff44 \ud835\udc1d \ud835\udc51 \ud835\udcb9 \ud835\udced \ud835\udd21 \ud835\udd55 \ud835\udd89 \ud835\uddbd \ud835\uddf1 \ud835\ude25 \ud835\ude8d".split(" ").indexOf(a)};
+sre.SemanticAttr.prototype.isMatchingFence_=function(a,b){return-1!=this.neutralFences.indexOf(a)?a==b:this.openClosePairs[a]==b||this.topBottomPairs[a]==b};sre.SemanticAttr.prototype.initMeaning_=function(){for(var a={},b=0,c;c=this.symbolSetToSemantic_[b];b++)c.set.forEach(function(b){a[b]={role:c.role||sre.SemanticAttr.Role.UNKNOWN,type:c.type||sre.SemanticAttr.Type.UNKNOWN,font:c.font||sre.SemanticAttr.Font.UNKNOWN}});return a};
+sre.SemanticAttr.prototype.lookupMeaning_=function(a){return this.meaning_[a]||{role:sre.SemanticAttr.Role.UNKNOWN,type:sre.SemanticAttr.Type.UNKNOWN,font:sre.SemanticAttr.Font.UNKNOWN}};sre.MathUtil={};sre.MathUtil.isMathmlNodeOfClass_=function(a,b){return-1!=b.indexOf(a.tagName.toUpperCase())};sre.MathUtil.isMathjaxNodeOfClass_=function(a,b){return"SPAN"==a.tagName?a.className.split(" ").some(function(a){return-1!=b.indexOf(a.toUpperCase())}):!1};sre.MathUtil.isMathNodeOfClass_=function(a,b){return a.nodeType==sre.DomUtil.NodeType.ELEMENT_NODE&&(sre.MathUtil.isMathmlNodeOfClass_(a,b)||sre.MathUtil.isMathjaxNodeOfClass_(a,b))};sre.MathUtil.TOKEN_LIST="MI MN MO MTEXT MSPACE MS".split(" ");
+sre.MathUtil.isToken=function(a){return sre.MathUtil.isMathNodeOfClass_(a,sre.MathUtil.TOKEN_LIST)};sre.MathUtil.LAYOUT_LIST="MROW MFRAC MSQRT MROOT MSTYLE MERROR MPADDED MPHANTOM MFENCED MENCLOSE".split(" ");sre.MathUtil.isLayout=function(a){return sre.MathUtil.isMathNodeOfClass_(a,sre.MathUtil.LAYOUT_LIST)};sre.MathUtil.SCRIPT_LIST="MSUB MSUP MSUBSUP MUNDER MOVER MUNDEROVER MMULTISCRIPTS MPRESCRIPTS".split(" ");sre.MathUtil.isScript=function(a){return sre.MathUtil.isMathNodeOfClass_(a,sre.MathUtil.SCRIPT_LIST)};
+sre.MathUtil.TABLES_LIST="MTABLE MLABELEDTR MTR MTD MALIGNGROUP MALIGNMARK".split(" ");sre.MathUtil.isTables=function(a){return sre.MathUtil.isMathNodeOfClass_(a,sre.MathUtil.TABLES_LIST)};sre.MathUtil.ELEMENTARY_LIST="MSTACK MLONGDIV MSGROUP MSROW MSCARRIES MSCARRY MSLINE".split(" ");sre.MathUtil.isElementary=function(a){return sre.MathUtil.isMathNodeOfClass_(a,sre.MathUtil.ELEMENTARY_LIST)};
+sre.MathUtil.MATHML_TAG_LIST=[sre.MathUtil.TOKEN_LIST,sre.MathUtil.LAYOUT_LIST,sre.MathUtil.SCRIPT_LIST,sre.MathUtil.TABLES_LIST,sre.MathUtil.ELEMENTARY_LIST].reduce(function(a,b){return a.concat(b)});sre.MathUtil.isMathmlTag=function(a){return sre.MathUtil.isMathNodeOfClass_(a,sre.MathUtil.MATHML_TAG_LIST)};sre.MathUtil.WHITESPACE_LIST=["MSROW","MROW","MSPACE","MPHANTOM","MPADDED"];sre.MathUtil.isWhitespace=function(a){return sre.MathUtil.isMathNodeOfClass_(a,sre.MathUtil.WHITESPACE_LIST)};
+sre.MathUtil.isNotWhitespace=function(a){return sre.MathUtil.isMathmlTag(a)&&!sre.MathUtil.isWhitespace(a)};sre.MathUtil.nextSeparatorFunction=function(a){if(a){if(a.match(/^\s+$/))return null;var b=a.replace(/\s/g,"").split("").filter(function(a){return a})}else b=[","];return function(){return 1<b.length?b.shift():b[0]}};sre.SemanticTree=function(a){this.idCounter_=0;this.mathml=a;this.root=this.parseMathml_(a)};sre.SemanticTree.Node=function(a){this.id=a;this.mathml=[];this.parent=null;this.type=sre.SemanticAttr.Type.UNKNOWN;this.role=sre.SemanticAttr.Role.UNKNOWN;this.font=sre.SemanticAttr.Font.UNKNOWN;this.embellished=null;this.fencePointer="";this.childNodes=[];this.textContent="";this.mathmlTree=null;this.contentNodes=[]};
+sre.SemanticTree.empty=function(){var a=sre.DomUtil.parseInput("<math/>"),b=new sre.SemanticTree(a);b.mathml=a;return b};sre.SemanticTree.fromNode=function(a,b){var c=sre.SemanticTree.empty();c.root=a;b&&(c.mathml=b);return c};sre.SemanticTree.fromRoot=function(a,b){for(var c=a;c.parent;)c=c.parent;c=sre.SemanticTree.fromNode(c);b&&(c.mathml=b);return c};
+sre.SemanticTree.Node.prototype.querySelectorAll=function(a){for(var b=[],c=0,d;d=this.childNodes[c];c++)b=b.concat(d.querySelectorAll(a));a(this)&&b.unshift(this);return b};sre.SemanticTree.prototype.xml=function(a){var b=sre.DomUtil.parseInput("<stree></stree>");a=this.root.xml(b.ownerDocument,a);b.appendChild(a);return b};
+sre.SemanticTree.Node.prototype.xml=function(a,b){var c=function(c,d){for(var e=d.map(function(c){return c.xml(a,b)}),f=a.createElement(c),l=0,k;k=e[l];l++)f.appendChild(k);return f},d=a.createElement(this.type);b||this.xmlAttributes_(d);d.textContent=this.textContent;0<this.contentNodes.length&&d.appendChild(c("content",this.contentNodes));0<this.childNodes.length&&d.appendChild(c("children",this.childNodes));return d};sre.SemanticTree.prototype.toString=function(a){return(new sre.SystemExternal.xmldom.XMLSerializer).serializeToString(this.xml(a))};
+sre.SemanticTree.prototype.formatXml=function(a){a=this.toString(a);return sre.DomUtil.formatXml(a)};sre.SemanticTree.Node.prototype.toString=function(a){var b=new sre.SystemExternal.xmldom.XMLSerializer,c=(new sre.SystemExternal.xmldom.DOMParser).parseFromString("","text/xml");return b.serializeToString(this.xml(c,a))};
+sre.SemanticTree.Node.prototype.xmlAttributes_=function(a){a.setAttribute("role",this.role);this.font!=sre.SemanticAttr.Font.UNKNOWN&&a.setAttribute("font",this.font);this.embellished&&a.setAttribute("embellished",this.embellished);this.fencePointer&&a.setAttribute("fencepointer",this.fencePointer);a.setAttribute("id",this.id)};sre.SemanticTree.prototype.createNode_=function(){return new sre.SemanticTree.Node(this.idCounter_++)};
+sre.SemanticTree.prototype.replaceNode_=function(a,b){var c=a.parent;c?c.replaceChild_(a,b):this.root=b};sre.SemanticTree.Node.prototype.updateContent_=function(a){a=a.trim();if(this.textContent!=a){var b=sre.SemanticAttr.lookupMeaning(a);this.textContent=a;this.role=b.role;this.type=b.type;this.font=b.font}};sre.SemanticTree.Node.prototype.addMathmlNodes_=function(a){for(var b=0,c;c=a[b];b++)-1==this.mathml.indexOf(c)&&this.mathml.push(c)};
+sre.SemanticTree.Node.prototype.removeMathmlNodes_=function(a){for(var b=this.mathml,c=0,d;d=a[c];c++)d=b.indexOf(d),-1!=d&&b.splice(d,1);this.mathml=b};sre.SemanticTree.Node.prototype.appendChild_=function(a){this.childNodes.push(a);this.addMathmlNodes_(a.mathml);a.parent=this};
+sre.SemanticTree.Node.prototype.replaceChild_=function(a,b){var c=this.childNodes.indexOf(a);if(-1!=c){a.parent=null;b.parent=this;this.childNodes[c]=b;var c=a.mathml.filter(function(a){return-1==b.mathml.indexOf(a)}),d=b.mathml.filter(function(b){return-1==a.mathml.indexOf(b)});this.removeMathmlNodes_(c);this.addMathmlNodes_(d)}};sre.SemanticTree.Node.prototype.appendContentNode_=function(a){a&&(this.contentNodes.push(a),this.addMathmlNodes_(a.mathml),a.parent=this)};
+sre.SemanticTree.Node.prototype.removeContentNode_=function(a){a&&(a=this.contentNodes.indexOf(a),-1!=a&&this.contentNodes.slice(a,1))};
+sre.SemanticTree.Node.prototype.equals=function(a){if(!a||this.type!==a.type||this.role!==a.role||this.textContent!==a.textContent||this.childNodes.length!==a.childNodes.length||this.contentNodes.length!==a.contentNodes.length)return!1;for(var b=0,c,d;c=this.childNodes[b],d=a.childNodes[b];b++)if(!c.equals(d))return!1;for(b=0;c=this.contentNodes[b],d=a.contentNodes[b];b++)if(!c.equals(d))return!1;return!0};
+sre.SemanticTree.prototype.parseMathml_=function(a){var b=sre.DomUtil.toArray(a.childNodes),c;switch(sre.SemanticUtil.tagName(a)){case "SEMANTICS":if(0<b.length){c=this.parseMathml_(b[0]);break}case "MATH":case "MROW":case "MPADDED":case "MSTYLE":return b=sre.SemanticUtil.purgeNodes(b),c=1==b.length?this.parseMathml_(b[0]):this.processRow_(this.parseMathmlChildren_(b)),c.mathml.unshift(a),c;case "MFRAC":sre.SemanticUtil.isZeroLength(a.getAttribute("linethickness"))?(c=this.makeBranchNode_(sre.SemanticAttr.Type.LINE,
+[this.parseMathml_(b[0])],[]),b=this.makeBranchNode_(sre.SemanticAttr.Type.LINE,[this.parseMathml_(b[1])],[]),c=this.makeBranchNode_(sre.SemanticAttr.Type.MULTILINE,[c,b],[])):c=this.makeFractionNode_(this.parseMathml_(b[0]),this.parseMathml_(b[1]));break;case "MSUB":case "MSUP":case "MSUBSUP":case "MOVER":case "MUNDER":case "MUNDEROVER":c=this.makeLimitNode_(sre.SemanticUtil.tagName(a),this.parseMathmlChildren_(b));break;case "MROOT":c=this.makeBranchNode_(sre.SemanticAttr.Type.ROOT,[this.parseMathml_(b[1]),
+this.parseMathml_(b[0])],[]);break;case "MSQRT":b=this.parseMathmlChildren_(sre.SemanticUtil.purgeNodes(b));c=this.makeBranchNode_(sre.SemanticAttr.Type.SQRT,[this.processRow_(b)],[]);break;case "MTABLE":c=this.makeBranchNode_(sre.SemanticAttr.Type.TABLE,this.parseMathmlChildren_(b),[]);sre.SemanticTree.tableIsMultiline_(c)&&this.tableToMultiline_(c);break;case "MTR":c=this.makeBranchNode_(sre.SemanticAttr.Type.ROW,this.parseMathmlChildren_(b),[]);c.role=sre.SemanticAttr.Role.TABLE;break;case "MTD":b=
+this.parseMathmlChildren_(sre.SemanticUtil.purgeNodes(b));c=this.makeBranchNode_(sre.SemanticAttr.Type.CELL,[this.processRow_(b)],[]);c.role=sre.SemanticAttr.Role.TABLE;break;case "MS":case "MTEXT":case "ANNOTATION-XML":c=this.makeLeafNode_(a);c.type=sre.SemanticAttr.Type.TEXT;"MS"===sre.SemanticUtil.tagName(a)&&(c.role=sre.SemanticAttr.Role.STRING);sre.SemanticTree.exprFont_(c);break;case "MI":c=this.makeIdentifierNode_(a);break;case "MN":c=this.makeLeafNode_(a);if(c.type==sre.SemanticAttr.Type.UNKNOWN||
+c.type==sre.SemanticAttr.Type.IDENTIFIER)c.type=sre.SemanticAttr.Type.NUMBER;sre.SemanticTree.numberRole_(c);sre.SemanticTree.exprFont_(c);break;case "MO":c=this.makeLeafNode_(a);c.type==sre.SemanticAttr.Type.UNKNOWN&&(c.type=sre.SemanticAttr.Type.OPERATOR);break;case "MFENCED":c=this.processMfenced_(a,this.parseMathmlChildren_(sre.SemanticUtil.purgeNodes(b)));c=this.processTablesInRow_([c])[0];break;case "MENCLOSE":b=this.parseMathmlChildren_(sre.SemanticUtil.purgeNodes(b));c=this.makeBranchNode_(sre.SemanticAttr.Type.ENCLOSE,
+[this.processRow_(b)],[]);c.role=a.getAttribute("notation")||sre.SemanticAttr.Role.UNKNOWN;break;case "MMULTISCRIPTS":c=this.processMultiScript_(b);break;case "ANNOTATION":case "NONE":c=this.makeEmptyNode_();break;case "MACTION":c=1<b.length?this.parseMathml_(b[1]):this.makeUnprocessed_(a);break;default:c=this.makeUnprocessed_(a)}c.mathml.unshift(a);c.mathmlTree=a;return c};sre.SemanticTree.prototype.parseMathmlChildren_=function(a){for(var b=[],c=0,d;d=a[c];c++)b.push(this.parseMathml_(d));return b};
+sre.SemanticTree.prototype.makeUnprocessed_=function(a){var b=this.createNode_();b.mathml=[a];return b};sre.SemanticTree.prototype.makeEmptyNode_=function(){var a=this.createNode_();a.type=sre.SemanticAttr.Type.EMPTY;return a};sre.SemanticTree.prototype.makeContentNode_=function(a){var b=this.createNode_();b.updateContent_(a);return b};sre.SemanticTree.prototype.makeMultipleContentNodes_=function(a,b){for(var c=[],d=0;d<a;d++)c.push(this.makeContentNode_(b));return c};
+sre.SemanticTree.prototype.makeLeafNode_=function(a){if(!a.textContent)return this.makeEmptyNode_();var b=this.makeContentNode_(a.textContent);b.font=a.getAttribute("mathvariant")||b.font;return b};sre.SemanticTree.prototype.makeBranchNode_=function(a,b,c,d){var e=this.createNode_();d&&e.updateContent_(d);e.type=a;e.childNodes=b;e.contentNodes=c;b.concat(c).forEach(function(a){a.parent=e;e.addMathmlNodes_(a.mathml)});return e};
+sre.SemanticTree.prototype.makeIdentifierNode_=function(a){var b=this.makeLeafNode_(a),c=a.getAttribute("mathvariant");if("MathML-Unit"===a.getAttribute("class"))b.type=sre.SemanticAttr.Type.IDENTIFIER,b.role=sre.SemanticAttr.Role.UNIT;else if(!c&&1==b.textContent.length&&(b.role==sre.SemanticAttr.Role.INTEGER||b.role==sre.SemanticAttr.Role.LATINLETTER||b.role==sre.SemanticAttr.Role.GREEKLETTER)&&b.font==sre.SemanticAttr.Font.NORMAL)return b.font=sre.SemanticAttr.Font.ITALIC,b;b.type==sre.SemanticAttr.Type.UNKNOWN&&
+(b.type=sre.SemanticAttr.Type.IDENTIFIER);sre.SemanticTree.exprFont_(b);return b};sre.SemanticTree.prototype.makeImplicitNode_=function(a){a=this.getMixedNumbers_(a);a=this.combineUnits_(a);if(1==a.length)return a[0];var b=this.makeMultipleContentNodes_(a.length-1,sre.SemanticAttr.invisibleTimes()),c=this.makeInfixNode_(a,b[0]);c.role=sre.SemanticAttr.Role.IMPLICIT;b.forEach(function(a){a.parent=c});c.contentNodes=b;return c};
+sre.SemanticTree.prototype.makeInfixNode_=function(a,b){var c=this.makeBranchNode_(sre.SemanticAttr.Type.INFIXOP,a,[b],sre.SemanticTree.getEmbellishedInner_(b).textContent);c.role=b.role;return c};sre.SemanticTree.prototype.makeConcatNode_=function(a,b,c){if(0==b.length)return a;var d=b.map(function(a){return sre.SemanticTree.getEmbellishedInner_(a).textContent}).join(" ");a=this.makeBranchNode_(c,[a],b,d);1<b.length&&(a.role=sre.SemanticAttr.Role.MULTIOP);return a};
+sre.SemanticTree.prototype.makePrefixNode_=function(a,b){for(var c=sre.SemanticTree.partitionNodes_(b,sre.SemanticTree.attrPred_("role","SUBTRACTION")),d=this.makeConcatNode_(a,c.comp.pop(),sre.SemanticAttr.Type.PREFIXOP);0<c.rel.length;)d=this.makeConcatNode_(d,[c.rel.pop()],sre.SemanticAttr.Type.PREFIXOP),d.role=sre.SemanticAttr.Role.NEGATIVE,d=this.makeConcatNode_(d,c.comp.pop(),sre.SemanticAttr.Type.PREFIXOP);return d};
+sre.SemanticTree.prototype.makePostfixNode_=function(a,b){return b.length?this.makeConcatNode_(a,b,sre.SemanticAttr.Type.POSTFIXOP):a};sre.SemanticTree.prototype.processRow_=function(a){a=a.filter(function(a){return!sre.SemanticTree.attrPred_("type","EMPTY")(a)});if(0==a.length)return this.makeEmptyNode_();a=this.getFencesInRow_(a);a=this.processTablesInRow_(a);a=this.getPunctuationInRow_(a);a=this.getTextInRow_(a);a=this.getFunctionsInRow_(a);return this.processRelationsInRow_(a)};
+sre.SemanticTree.prototype.combineUnits_=function(a){var b=sre.SemanticTree.partitionNodes_(a,function(a){return!sre.SemanticTree.attrPred_("role","UNIT")(a)});if(a.length===b.rel.length)return b.rel;a=[];do{var c=b.comp.shift(),d=b.rel.shift();1==c.length&&(a=a.concat(c));if(1<c.length){var e=this.makeContentNode_(sre.SemanticAttr.invisibleTimes()),c=this.makeInfixNode_(c,e);c.role=sre.SemanticAttr.Role.UNIT;a.push(c)}d&&a.push(d)}while(d);return a};
+sre.SemanticTree.prototype.getMixedNumbers_=function(a){var b=sre.SemanticTree.partitionNodes_(a,function(a){return sre.SemanticTree.attrPred_("type","FRACTION")(a)&&sre.SemanticTree.attrPred_("role","VULGAR")(a)});if(!b.rel.length)return a;a=[];for(var c=0,d;d=b.rel[c];c++){var e=b.comp[c],f=e.length-1;e[f]&&sre.SemanticTree.attrPred_("type","NUMBER")(e[f])&&sre.SemanticTree.attrPred_("role","INTEGER")(e[f])?(d=this.makeBranchNode_(sre.SemanticAttr.Type.NUMBER,[e[f],d],[]),d.role=sre.SemanticAttr.Role.MIXED,
+a=a.concat(e.slice(0,f))):a=a.concat(e);a.push(d)}return a.concat(b.comp[b.comp.length-1])};sre.SemanticTree.prototype.getTextInRow_=function(a){if(1>=a.length)return a;var b=sre.SemanticTree.partitionNodes_(a,sre.SemanticTree.attrPred_("type","TEXT"));if(0==b.rel.length)return a;a=[];var c=b.comp[0];0<c.length&&a.push(this.processRow_(c));for(var d=0;c=b.rel[d];d++)a.push(c),c=b.comp[d+1],0<c.length&&a.push(this.processRow_(c));return[this.makeDummyNode_(a)]};
+sre.SemanticTree.prototype.processRelationsInRow_=function(a){var b=sre.SemanticTree.partitionNodes_(a,sre.SemanticTree.isRelation_),c=b.rel[0];if(!c)return this.processOperationsInRow_(a);if(1==a.length)return a[0];a=b.comp.map(goog.bind(this.processOperationsInRow_,this));if(b.rel.some(function(a){return!a.equals(c)}))return a=this.makeBranchNode_(sre.SemanticAttr.Type.MULTIREL,a,b.rel),b.rel.every(function(a){return a.role===c.role})&&(a.role=c.role),a;a=this.makeBranchNode_(sre.SemanticAttr.Type.RELSEQ,
+a,b.rel,sre.SemanticTree.getEmbellishedInner_(c).textContent);a.role=c.role;return a};
+sre.SemanticTree.prototype.processOperationsInRow_=function(a){if(0==a.length)return this.makeEmptyNode_();if(1==a.length)return a[0];for(var b=[];0<a.length&&sre.SemanticTree.isOperator_(a[0]);)b.push(a.shift());if(0==a.length)return this.makePrefixNode_(b.pop(),b);if(1==a.length)return this.makePrefixNode_(a[0],b);a=sre.SemanticTree.sliceNodes_(a,sre.SemanticTree.isOperator_);b=this.makePrefixNode_(this.makeImplicitNode_(a.head),b);return a.div?this.makeOperationsTree_(a.tail,b,a.div):b};
+sre.SemanticTree.prototype.makeOperationsTree_=function(a,b,c,d){d=d||[];if(0==a.length)return d.unshift(c),b.type==sre.SemanticAttr.Type.INFIXOP?(d=this.makePostfixNode_(b.childNodes.pop(),d),b.appendChild_(d),b):this.makePostfixNode_(b,d);a=sre.SemanticTree.sliceNodes_(a,sre.SemanticTree.isOperator_);if(0==a.head.length)return d.push(a.div),this.makeOperationsTree_(a.tail,b,c,d);d=this.makePrefixNode_(this.makeImplicitNode_(a.head),d);b=this.appendOperand_(b,c,d);return a.div?this.makeOperationsTree_(a.tail,
+b,a.div,[]):b};sre.SemanticTree.prototype.appendOperand_=function(a,b,c){return a.type!=sre.SemanticAttr.Type.INFIXOP?this.makeInfixNode_([a,c],b):this.appendExistingOperator_(a,b,c)?a:b.role==sre.SemanticAttr.Role.MULTIPLICATION?this.appendMultiplicativeOp_(a,b,c):this.appendAdditiveOp_(a,b,c)};
+sre.SemanticTree.prototype.appendMultiplicativeOp_=function(a,b,c){if(a.role==sre.SemanticAttr.Role.IMPLICIT)return this.makeInfixNode_([a,c],b);for(var d=a,e=a.childNodes[a.childNodes.length-1];e&&e.type==sre.SemanticAttr.Type.INFIXOP;)d=e,e=d.childNodes[a.childNodes.length-1];b=this.makeInfixNode_([d.childNodes.pop(),c],b);d.appendChild_(b);return a};sre.SemanticTree.prototype.appendAdditiveOp_=function(a,b,c){return this.makeInfixNode_([a,c],b)};
+sre.SemanticTree.prototype.appendExistingOperator_=function(a,b,c){return a&&a.type==sre.SemanticAttr.Type.INFIXOP&&a.role!==sre.SemanticAttr.Role.IMPLICIT?a.contentNodes[0].equals(b)?(a.appendContentNode_(b),a.appendChild_(c),!0):this.appendExistingOperator_(a.childNodes[a.childNodes.length-1],b,c):!1};
+sre.SemanticTree.prototype.getFencesInRow_=function(a){a=sre.SemanticTree.partitionNodes_(a,sre.SemanticTree.isFence_);a=sre.SemanticTree.purgeFences_(a);var b=a.comp.shift();return this.processFences_(a.rel,a.comp,[],[b])};
+sre.SemanticTree.prototype.processFences_=function(a,b,c,d){if(0==a.length&&0==c.length)return d[0];var e=sre.SemanticTree.attrPred_("role","OPEN");if(0==a.length){for(a=d.shift();0<c.length;){if(e(c[0]))b=c.shift(),sre.SemanticTree.fenceToPunct_(b),a.push(b);else{c=sre.SemanticTree.sliceNodes_(c,e);var f=c.head.length-1,g=this.processNeutralFences_(c.head,d.slice(0,f));d=d.slice(f);a.push.apply(a,g);c.div&&c.tail.unshift(c.div);c=c.tail}a.push.apply(a,d.shift())}return a}f=c[c.length-1];g=a[0].role;
+if(g==sre.SemanticAttr.Role.OPEN||g==sre.SemanticAttr.Role.NEUTRAL&&(!f||a[0].textContent!=f.textContent))return c.push(a.shift()),(e=b.shift())&&d.push(e),this.processFences_(a,b,c,d);if(f&&(g==sre.SemanticAttr.Role.CLOSE&&f.role==sre.SemanticAttr.Role.OPEN||g==sre.SemanticAttr.Role.NEUTRAL&&a[0].textContent==f.textContent))return e=this.makeHorizontalFencedNode_(c.pop(),a.shift(),d.pop()),d.push(d.pop().concat([e],b.shift())),this.processFences_(a,b,c,d);if(f&&g==sre.SemanticAttr.Role.CLOSE&&f.role==
+sre.SemanticAttr.Role.NEUTRAL&&c.some(e))return c=sre.SemanticTree.sliceNodes_(c,e,!0),e=d.pop(),f=d.length-c.tail.length+1,g=this.processNeutralFences_(c.tail,d.slice(f)),d=d.slice(0,f),e=this.makeHorizontalFencedNode_(c.div,a.shift(),d.pop().concat(g,e)),d.push(d.pop().concat([e],b.shift())),this.processFences_(a,b,c.head,d);e=a.shift();sre.SemanticTree.fenceToPunct_(e);d.push(d.pop().concat([e],b.shift()));return this.processFences_(a,b,c,d)};
+sre.SemanticTree.prototype.processNeutralFences_=function(a,b){if(0==a.length)return a;if(1==a.length)return sre.SemanticTree.fenceToPunct_(a[0]),a;var c=a.shift(),d=sre.SemanticTree.sliceNodes_(a,function(a){return sre.SemanticTree.getEmbellishedInner_(a).textContent==sre.SemanticTree.getEmbellishedInner_(c).textContent});if(!d.div){sre.SemanticTree.fenceToPunct_(c);var e=b.shift();e.unshift(c);return e.concat(this.processNeutralFences_(a,b))}var f=this.combineFencedContent_(c,d.div,d.head,b);return 0<
+d.tail.length?(e=f.shift(),d=this.processNeutralFences_(d.tail,f),e.concat(d)):f[0]};sre.SemanticTree.prototype.combineFencedContent_=function(a,b,c,d){if(0==c.length)return a=this.makeHorizontalFencedNode_(a,b,d.shift()),0<d.length?d[0].unshift(a):d=[[a]],d;var e=d.shift(),f=c.length-1,g=d.slice(0,f);d=d.slice(f);f=d.shift();c=this.processNeutralFences_(c,g);e.push.apply(e,c);e.push.apply(e,f);a=this.makeHorizontalFencedNode_(a,b,e);0<d.length?d[0].unshift(a):d=[[a]];return d};
+sre.SemanticTree.fenceToPunct_=function(a){var b;switch(a.role){case sre.SemanticAttr.Role.NEUTRAL:b=sre.SemanticAttr.Role.VBAR;break;case sre.SemanticAttr.Role.OPEN:b=sre.SemanticAttr.Role.OPENFENCE;break;case sre.SemanticAttr.Role.CLOSE:b=sre.SemanticAttr.Role.CLOSEFENCE;break;default:return}for(;a.embellished;)a.embellished=sre.SemanticAttr.Type.PUNCTUATION,a.role=b,a=a.childNodes[0];a.type=sre.SemanticAttr.Type.PUNCTUATION;a.role=b};
+sre.SemanticTree.prototype.makeHorizontalFencedNode_=function(a,b,c){c=this.processRow_(c);b=this.makeBranchNode_(sre.SemanticAttr.Type.FENCED,[c],[a,b]);b.role=a.role==sre.SemanticAttr.Role.OPEN?sre.SemanticAttr.Role.LEFTRIGHT:a.role;return sre.SemanticTree.rewriteFencedNode_(b)};
+sre.SemanticTree.prototype.getPunctuationInRow_=function(a){var b=sre.SemanticTree.partitionNodes_(a,function(a){return sre.SemanticTree.isPunctuation_(a)&&!sre.SemanticTree.attrPred_("role","ELLIPSIS")(a)});if(0==b.rel.length)return a;a=[];var c=b.comp.shift();0<c.length&&a.push(this.processRow_(c));for(var d=0;0<b.comp.length;)a.push(b.rel[d++]),c=b.comp.shift(),0<c.length&&a.push(this.processRow_(c));return[this.makePunctuatedNode_(a,b.rel)]};
+sre.SemanticTree.prototype.makePunctuatedNode_=function(a,b){var c=this.makeBranchNode_(sre.SemanticAttr.Type.PUNCTUATED,a,b);if(b.length==a.length){var d=b[0].role;if(d!=sre.SemanticAttr.Role.UNKNOWN&&b.every(function(a){return a.role==d}))return c.role=d,c}1==b.length&&a[0].type==sre.SemanticAttr.Type.PUNCTUATION?c.role=sre.SemanticAttr.Role.STARTPUNCT:1==b.length&&a[a.length-1].type==sre.SemanticAttr.Type.PUNCTUATION?c.role=sre.SemanticAttr.Role.ENDPUNCT:b.every(sre.SemanticTree.attrPred_("role",
+"DUMMY"))?c.role=sre.SemanticAttr.Role.TEXT:c.role=sre.SemanticAttr.Role.SEQUENCE;return c};sre.SemanticTree.prototype.makeDummyNode_=function(a){var b=this.makeMultipleContentNodes_(a.length-1,sre.SemanticAttr.invisibleComma());b.forEach(function(a){a.role=sre.SemanticAttr.Role.DUMMY});return this.makePunctuatedNode_(a,b)};
+sre.SemanticTree.prototype.makeLimitNode_=function(a,b){var c=b[0],d=sre.SemanticTree.attrPred_("type","FUNCTION")(c),d=sre.SemanticTree.attrPred_("type","LARGEOP")(c)||sre.SemanticTree.attrPred_("type","LIMBOTH")(c)||sre.SemanticTree.attrPred_("type","LIMLOWER")(c)||sre.SemanticTree.attrPred_("type","LIMUPPER")(c)||d&&sre.SemanticTree.attrPred_("role","LIMFUNC")(c),e=sre.SemanticAttr.Type.UNKNOWN;if(d)switch(a){case "MSUB":case "MUNDER":e=sre.SemanticAttr.Type.LIMLOWER;break;case "MSUP":case "MOVER":e=
+sre.SemanticAttr.Type.LIMUPPER;break;case "MSUBSUP":case "MUNDEROVER":e=sre.SemanticAttr.Type.LIMBOTH}else switch(a){case "MSUB":e=sre.SemanticAttr.Type.SUBSCRIPT;break;case "MSUP":e=sre.SemanticAttr.Type.SUPERSCRIPT;break;case "MSUBSUP":var f=this.makeBranchNode_(sre.SemanticAttr.Type.SUBSCRIPT,[c,b[1]],[]);f.role=sre.SemanticAttr.Role.SUBSUP;b=[f,b[2]];e=sre.SemanticAttr.Type.SUPERSCRIPT;break;case "MOVER":e=sre.SemanticAttr.Type.OVERSCORE;sre.SemanticTree.isAccent_(b[1])&&(b[1].role=sre.SemanticAttr.Role.OVERACCENT);
+break;case "MUNDER":e=sre.SemanticAttr.Type.UNDERSCORE;sre.SemanticTree.isAccent_(b[1])&&(b[1].role=sre.SemanticAttr.Role.UNDERACCENT);break;default:f=sre.SemanticTree.isAccent_(b[1]),d=sre.SemanticTree.isAccent_(b[2]),f&&(b[1].role=sre.SemanticAttr.Role.UNDERACCENT),d&&(b[2].role=sre.SemanticAttr.Role.OVERACCENT),d&&!f?(f=this.makeBranchNode_(sre.SemanticAttr.Type.OVERSCORE,[c,b[2]],[]),f.role=c.role,b=[f,b[1]],e=sre.SemanticAttr.Type.UNDERSCORE):(f=this.makeBranchNode_(sre.SemanticAttr.Type.UNDERSCORE,
+[c,b[1]],[]),f.role=sre.SemanticAttr.Role.UNDEROVER,b=[f,b[2]],e=sre.SemanticAttr.Type.OVERSCORE)}d=this.makeBranchNode_(e,b,[]);e=sre.SemanticTree.isEmbellished_(c);f&&(f.embellished=e);d.embellished=e;d.role=c.role;return d};
+sre.SemanticTree.isAccent_=function(a){return sre.SemanticTree.attrPred_("type","FENCE")(a)||sre.SemanticTree.attrPred_("type","PUNCTUATION")(a)||sre.SemanticTree.attrPred_("type","OPERATOR")(a)||sre.SemanticTree.attrPred_("type","RELATION")(a)||sre.SemanticTree.attrPred_("type","IDENTIFIER")(a)&&sre.SemanticTree.attrPred_("role","UNKNOWN")(a)&&!a.textContent.match(new RegExp(sre.SemanticAttr.getInstance().allLetters.join("|")))};
+sre.SemanticTree.prototype.getFunctionsInRow_=function(a,b){var c=b||[];if(0==a.length)return c;var d=a.shift(),e=sre.SemanticTree.classifyFunction_(d,a);if(!e)return c.push(d),this.getFunctionsInRow_(a,c);var f=this.getFunctionsInRow_(a,[]),d=this.getFunctionArgs_(d,f,e);return c.concat(d)};
+sre.SemanticTree.classifyFunction_=function(a,b){if(a.type==sre.SemanticAttr.Type.APPL||a.type==sre.SemanticAttr.Type.BIGOP||a.type==sre.SemanticAttr.Type.INTEGRAL)return"";if(b[0]&&b[0].textContent==sre.SemanticAttr.functionApplication()){b.shift();var c=sre.SemanticAttr.Role.SIMPLEFUNC;if(a.role===sre.SemanticAttr.Role.PREFIXFUNC||a.role===sre.SemanticAttr.Role.LIMFUNC)c=a.role;sre.SemanticTree.propagateFunctionRole_(a,c);return"prefix"}switch(a.role){case sre.SemanticAttr.Role.INTEGRAL:return"integral";
+case sre.SemanticAttr.Role.SUM:return"bigop";case sre.SemanticAttr.Role.PREFIXFUNC:case sre.SemanticAttr.Role.LIMFUNC:return"prefix";default:if(a.type==sre.SemanticAttr.Type.IDENTIFIER||a.role==sre.SemanticAttr.Role.LATINLETTER||a.role==sre.SemanticAttr.Role.GREEKLETTER||a.role==sre.SemanticAttr.Role.OTHERLETTER)return"simple"}return""};
+sre.SemanticTree.propagateFunctionRole_=function(a,b){a&&(sre.SemanticTree.attrPred_("role","SUBSUP")(a)||(a.role=b),sre.SemanticTree.propagateFunctionRole_(a.childNodes[0],b))};
+sre.SemanticTree.prototype.getFunctionArgs_=function(a,b,c){switch(c){case "integral":b=this.getIntegralArgs_(b);var d=this.processRow_(b.integrand);a=this.makeIntegralNode_(a,d,b.intvar);b.rest.unshift(a);return b.rest;case "prefix":if(b[0]&&b[0].type==sre.SemanticAttr.Type.FENCED)return a=this.makeFunctionNode_(a,b.shift()),b.unshift(a),b;case "bigop":d=sre.SemanticTree.sliceNodes_(b,sre.SemanticTree.prefixFunctionBoundary_);if(!d.head.length)return b.unshift(a),b;b=this.processRow_(d.head);a="prefix"==
+c?this.makeFunctionNode_(a,b):this.makeBigOpNode_(a,b);d.div&&d.tail.unshift(d.div);d.tail.unshift(a);return d.tail;default:if(0==b.length)return[a];d=b[0];if(d.type==sre.SemanticAttr.Type.FENCED&&d.role!=sre.SemanticAttr.Role.NEUTRAL&&this.simpleFunctionHeuristic_(d))return sre.SemanticTree.propagateFunctionRole_(a,sre.SemanticAttr.Role.SIMPLEFUNC),a=this.makeFunctionNode_(a,b.shift()),b.unshift(a),b;b.unshift(a);return b}};
+sre.SemanticTree.prototype.getIntegralArgs_=function(a,b){var c=b||[];if(0==a.length)return{integrand:c,intvar:null,rest:a};var d=a[0];if(sre.SemanticTree.generalFunctionBoundary_(d))return{integrand:c,intvar:null,rest:a};if(sre.SemanticTree.integralDxBoundarySingle_(d))return{integrand:c,intvar:d,rest:a.slice(1)};if(a[1]&&sre.SemanticTree.integralDxBoundary_(d,a[1])){var e=this.makeContentNode_(sre.SemanticAttr.invisibleComma()),d=this.makePunctuatedNode_([d,e,a[1]],[e]);d.role=sre.SemanticAttr.Role.INTEGRAL;
+return{integrand:c,intvar:d,rest:a.slice(2)}}c.push(a.shift());return this.getIntegralArgs_(a,c)};
+sre.SemanticTree.prototype.makeFunctionNode_=function(a,b){var c=this.makeContentNode_(sre.SemanticAttr.functionApplication());c.type=sre.SemanticAttr.Type.PUNCTUATION;c.role=sre.SemanticAttr.Role.APPLICATION;var d=sre.SemanticTree.getFunctionOp_(a,function(a){return sre.SemanticTree.attrPred_("type","FUNCTION")(a)||sre.SemanticTree.attrPred_("type","IDENTIFIER")(a)&&sre.SemanticTree.attrPred_("role","SIMPLEFUNC")(a)});return this.makeFunctionalNode_(sre.SemanticAttr.Type.APPL,[a,b],d,[c])};
+sre.SemanticTree.prototype.makeBigOpNode_=function(a,b){var c=sre.SemanticTree.getFunctionOp_(a,sre.SemanticTree.attrPred_("type","LARGEOP"));return this.makeFunctionalNode_(sre.SemanticAttr.Type.BIGOP,[a,b],c,[])};sre.SemanticTree.prototype.makeIntegralNode_=function(a,b,c){b=b||this.makeEmptyNode_();c=c||this.makeEmptyNode_();var d=sre.SemanticTree.getFunctionOp_(a,sre.SemanticTree.attrPred_("type","LARGEOP"));return this.makeFunctionalNode_(sre.SemanticAttr.Type.INTEGRAL,[a,b,c],d,[])};
+sre.SemanticTree.prototype.makeFunctionalNode_=function(a,b,c,d){var e=b[0];if(c){var f=c.parent;d.push(c)}a=this.makeBranchNode_(a,b,d);a.role=e.role;f&&(c.parent=f);return a};sre.SemanticTree.getFunctionOp_=function(a,b){if(b(a))return a;for(var c=0,d;d=a.childNodes[c];c++)if(d=sre.SemanticTree.getFunctionOp_(d,b))return d;return null};
+sre.SemanticTree.prototype.simpleFunctionHeuristic_=function(a){a=a.childNodes;if(0==a.length)return!0;if(1<a.length)return!1;a=a[0];return a.type!=sre.SemanticAttr.Type.INFIXOP||a.role==sre.SemanticAttr.Role.IMPLICIT&&!a.childNodes.some(sre.SemanticTree.attrPred_("type","INFIXOP"))?!0:!1};sre.SemanticTree.prefixFunctionBoundary_=function(a){return sre.SemanticTree.isOperator_(a)||sre.SemanticTree.generalFunctionBoundary_(a)};
+sre.SemanticTree.integralDxBoundary_=function(a,b){return!!b&&sre.SemanticTree.attrPred_("type","IDENTIFIER")(b)&&sre.SemanticAttr.isCharacterD(a.textContent)};sre.SemanticTree.integralDxBoundarySingle_=function(a){if(sre.SemanticTree.attrPred_("type","IDENTIFIER")(a)){var b=a.textContent[0];return b&&a.textContent[1]&&sre.SemanticAttr.isCharacterD(b)}return!1};sre.SemanticTree.generalFunctionBoundary_=function(a){return sre.SemanticTree.isRelation_(a)||sre.SemanticTree.isPunctuation_(a)};
+sre.SemanticTree.prototype.processTablesInRow_=function(a){a=sre.SemanticTree.partitionNodes_(a,sre.SemanticTree.tableIsMatrixOrVector_);for(var b=[],c=0,d;d=a.rel[c];c++)b=b.concat(a.comp.shift()),b.push(this.tableToMatrixOrVector_(d));b=b.concat(a.comp.shift());a=sre.SemanticTree.partitionNodes_(b,sre.SemanticTree.isTableOrMultiline_);b=[];for(c=0;d=a.rel[c];c++){var e=a.comp.shift();sre.SemanticTree.tableIsCases_(d,e)&&this.tableToCases_(d,e.pop());b=b.concat(e);b.push(d)}return b.concat(a.comp.shift())};
+sre.SemanticTree.isTableOrMultiline_=function(a){return!!a&&(sre.SemanticTree.attrPred_("type","TABLE")(a)||sre.SemanticTree.attrPred_("type","MULTILINE")(a))};sre.SemanticTree.tableIsMatrixOrVector_=function(a){return!!a&&sre.SemanticTree.attrPred_("type","FENCED")(a)&&(sre.SemanticTree.attrPred_("role","LEFTRIGHT")(a)||sre.SemanticTree.attrPred_("role","NEUTRAL")(a))&&1==a.childNodes.length&&sre.SemanticTree.isTableOrMultiline_(a.childNodes[0])};
+sre.SemanticTree.prototype.tableToMatrixOrVector_=function(a){var b=a.childNodes[0];sre.SemanticTree.attrPred_("type","MULTILINE")(b)?this.tableToVector_(a):this.tableToMatrix_(a);a.contentNodes.forEach(goog.bind(b.appendContentNode_,b));a=0;for(var c;c=b.childNodes[a];a++)sre.SemanticTree.assignRoleToRow_(c,sre.SemanticTree.getComponentRoles_(b));b.parent=null;return b};
+sre.SemanticTree.prototype.tableToVector_=function(a){var b=a.childNodes[0];b.type=sre.SemanticAttr.Type.VECTOR;1===b.childNodes.length?this.tableToSquare_(a):2===b.childNodes.length&&(b.role=sre.SemanticAttr.Role.BINOMIAL)};
+sre.SemanticTree.prototype.tableToMatrix_=function(a){var b=a.childNodes[0];b.type=sre.SemanticAttr.Type.MATRIX;b.childNodes&&0<b.childNodes.length&&b.childNodes[0].childNodes&&b.childNodes.length===b.childNodes[0].childNodes.length?this.tableToSquare_(a):b.childNodes&&1===b.childNodes.length&&(b.role=sre.SemanticAttr.Role.ROWVECTOR)};
+sre.SemanticTree.prototype.tableToSquare_=function(a){var b=a.childNodes[0];sre.SemanticTree.attrPred_("role","NEUTRAL")(a)?b.role=sre.SemanticAttr.Role.DETERMINANT:b.role=sre.SemanticAttr.Role.SQUAREMATRIX};sre.SemanticTree.getComponentRoles_=function(a){var b=a.role;return b&&b!==sre.SemanticAttr.Role.UNKNOWN?b:sre.SemanticAttr.Role[a.type.toUpperCase()]||sre.SemanticAttr.Role.UNKNOWN};
+sre.SemanticTree.tableIsCases_=function(a,b){return 0<b.length&&sre.SemanticTree.attrPred_("role","OPENFENCE")(b[b.length-1])};sre.SemanticTree.prototype.tableToCases_=function(a,b){for(var c=0,d;d=a.childNodes[c];c++)sre.SemanticTree.assignRoleToRow_(d,sre.SemanticAttr.Role.CASES);a.type=sre.SemanticAttr.Type.CASES;a.appendContentNode_(b);return a};sre.SemanticTree.tableIsMultiline_=function(a){return a.childNodes.every(function(a){return 1>=a.childNodes.length})};
+sre.SemanticTree.prototype.tableToMultiline_=function(a){a.type=sre.SemanticAttr.Type.MULTILINE;for(var b=0,c;c=a.childNodes[b];b++)sre.SemanticTree.rowToLine_(c,sre.SemanticAttr.Role.MULTILINE)};sre.SemanticTree.rowToLine_=function(a,b){var c=b||sre.SemanticAttr.Role.UNKNOWN;sre.SemanticTree.attrPred_("type","ROW")(a)&&1==a.childNodes.length&&sre.SemanticTree.attrPred_("type","CELL")(a.childNodes[0])&&(a.type=sre.SemanticAttr.Type.LINE,a.role=c,a.childNodes=a.childNodes[0].childNodes)};
+sre.SemanticTree.assignRoleToRow_=function(a,b){if(sre.SemanticTree.attrPred_("type","LINE")(a))a.role=b;else if(sre.SemanticTree.attrPred_("type","ROW")(a)){a.role=b;var c=sre.SemanticTree.attrPred_("type","CELL");a.childNodes.forEach(function(a){c(a)&&(a.role=b)})}};
+sre.SemanticTree.sliceNodes_=function(a,b,c){c&&a.reverse();for(var d=[],e=0,f;f=a[e];e++){if(b(f))return c?{head:a.slice(e+1).reverse(),div:f,tail:d.reverse()}:{head:d,div:f,tail:a.slice(e+1)};d.push(f)}return c?{head:[],div:null,tail:d.reverse()}:{head:d,div:null,tail:[]}};sre.SemanticTree.partitionNodes_=function(a,b){var c=a,d=[],e=[];do{var f=sre.SemanticTree.sliceNodes_(c,b);e.push(f.head);d.push(f.div);c=f.tail}while(f.div);d.pop();return{rel:d,comp:e}};
+sre.SemanticTree.attrPred_=function(a,b){return function(c){c=c[a];var d;a:switch(a){case "role":d=sre.SemanticAttr.Role[b];break a;case "font":d=sre.SemanticAttr.Font[b];break a;default:d=sre.SemanticAttr.Type[b]}return c==d}};
+sre.SemanticTree.prototype.processMfenced_=function(a,b){var c=sre.SemanticTree.getAttribute_(a,"separators",","),d=sre.SemanticTree.getAttribute_(a,"open","("),e=sre.SemanticTree.getAttribute_(a,"close",")");if(c&&0<b.length){var f=sre.MathUtil.nextSeparatorFunction(c),g=[b.shift()];b.forEach(goog.bind(function(a){g.push(this.makeContentNode_(f()));g.push(a)},this));b=g}if(d&&e)return this.makeHorizontalFencedNode_(this.makeContentNode_(d),this.makeContentNode_(e),b);d&&b.unshift(this.makeContentNode_(d));
+e&&b.push(this.makeContentNode_(e));return this.processRow_(b)};sre.SemanticTree.getAttribute_=function(a,b,c){if(!a.hasAttribute(b))return c;a=a.getAttribute(b);return a.match(/^\s*$/)?null:a};
+sre.SemanticTree.numberRole_=function(a){if(a.role===sre.SemanticAttr.Role.UNKNOWN){var b=sre.SemanticUtil.splitUnicode(a.textContent).map(sre.SemanticAttr.lookupMeaning);b.every(function(a){return a.type==sre.SemanticAttr.Type.NUMBER&&a.role==sre.SemanticAttr.Role.INTEGER||a.type==sre.SemanticAttr.Type.PUNCTUATION&&a.role==sre.SemanticAttr.Role.COMMA})?a.role=sre.SemanticAttr.Role.INTEGER:b.every(function(a){return a.type==sre.SemanticAttr.Type.NUMBER&&a.role==sre.SemanticAttr.Role.INTEGER||a.type==
+sre.SemanticAttr.Type.PUNCTUATION})?a.role=sre.SemanticAttr.Role.FLOAT:a.role=sre.SemanticAttr.Role.OTHERNUMBER}};sre.SemanticTree.exprFont_=function(a){if(a.font===sre.SemanticAttr.Font.UNKNOWN){var b=sre.SemanticUtil.splitUnicode(a.textContent).map(sre.SemanticAttr.lookupMeaning).reduce(function(a,b){return a&&b.font&&b.font!=sre.SemanticAttr.Font.UNKNOWN&&b.font!=a?a==sre.SemanticAttr.Font.UNKNOWN?b.font:null:a},sre.SemanticAttr.Font.UNKNOWN);b&&(a.font=b)}};
+sre.SemanticTree.prototype.makeFractionNode_=function(a,b){var c=this.makeBranchNode_(sre.SemanticAttr.Type.FRACTION,[a,b],[]);c.role=c.childNodes.every(function(a){return sre.SemanticTree.attrPred_("role","INTEGER")(a)})?sre.SemanticAttr.Role.VULGAR:c.childNodes.every(function(a){return sre.SemanticTree.attrPred_("role","UNIT")(a)})?sre.SemanticAttr.Role.UNIT:sre.SemanticAttr.Role.DIVISION;return c};
+sre.SemanticTree.prototype.processMultiScript_=function(a){if(!a.length)return this.makeEmptyNode_();var b=this.parseMathml_(a.shift());if(!a.length)return b;for(var c=[],d=[],e=[],f=[],g=!1,h=0,l=0,k;k=a[l];l++)"MPRESCRIPTS"===sre.SemanticUtil.tagName(k)?(g=!0,h=0):(g?h&1?c.push(k):d.push(k):h&1?e.push(k):f.push(k),h++);if(!sre.SemanticUtil.purgeNodes(c).length&&!sre.SemanticUtil.purgeNodes(d).length){a=sre.SemanticUtil.purgeNodes(e);c=sre.SemanticUtil.purgeNodes(f);if(!a.length&&!c.length)return b;
+d=c.length?a.length?"MSUBSUP":"MSUB":"MSUP";b=[b];c.length&&b.push(this.makeScriptNode_(f,sre.SemanticAttr.Role.RIGHTSUB,!0));a.length&&b.push(this.makeScriptNode_(e,sre.SemanticAttr.Role.RIGHTSUPER,!0));return this.makeLimitNode_(d,b)}e=this.makeBranchNode_(sre.SemanticAttr.Type.TENSOR,[b,this.makeScriptNode_(d,sre.SemanticAttr.Role.LEFTSUB),this.makeScriptNode_(c,sre.SemanticAttr.Role.LEFTSUPER),this.makeScriptNode_(f,sre.SemanticAttr.Role.RIGHTSUB),this.makeScriptNode_(e,sre.SemanticAttr.Role.RIGHTSUPER)],
+[]);e.role=b.role;e.embellished=sre.SemanticTree.isEmbellished_(b);return e};sre.SemanticTree.prototype.makeScriptNode_=function(a,b,c){switch(a.length){case 0:a=this.makeEmptyNode_();break;case 1:a=this.parseMathml_(a[0]);if(c)return a;break;default:a=this.makeDummyNode_(this.parseMathmlChildren_(a))}a.role=b;return a};sre.SemanticTree.isEmbellished_=function(a){return a.embellished?a.embellished:sre.SemanticAttr.isEmbellishedType(a.type)?a.type:null};
+sre.SemanticTree.isOperator_=function(a){return sre.SemanticTree.attrPred_("type","OPERATOR")(a)||sre.SemanticTree.attrPred_("embellished","OPERATOR")(a)};sre.SemanticTree.isRelation_=function(a){return sre.SemanticTree.attrPred_("type","RELATION")(a)||sre.SemanticTree.attrPred_("embellished","RELATION")(a)};sre.SemanticTree.isPunctuation_=function(a){return sre.SemanticTree.attrPred_("type","PUNCTUATION")(a)||sre.SemanticTree.attrPred_("embellished","PUNCTUATION")(a)};
+sre.SemanticTree.isFence_=function(a){return sre.SemanticTree.attrPred_("type","FENCE")(a)||sre.SemanticTree.attrPred_("embellished","FENCE")(a)};sre.SemanticTree.getEmbellishedInner_=function(a){return a&&a.embellished&&0<a.childNodes.length?sre.SemanticTree.getEmbellishedInner_(a.childNodes[0]):a};
+sre.SemanticTree.purgeFences_=function(a){var b=a.rel;a=a.comp;for(var c=[],d=[];0<b.length;){var e=b.shift(),f=a.shift();sre.SemanticTree.isElligibleFence_(e)?(c.push(e),d.push(f)):(sre.SemanticTree.fenceToPunct_(e),f.push(e),f=f.concat(a.shift()),a.unshift(f))}d.push(a.shift());return{rel:c,comp:d}};
+sre.SemanticTree.isElligibleFence_=function(a){if(!a||!sre.SemanticTree.isFence_(a))return!1;if(!a.embellished)return!0;var b=function(a){return a.embellished?!(!sre.SemanticTree.attrPred_("type","TENSOR")(a)||sre.SemanticTree.attrPred_("type","EMPTY")(a.childNodes[1])&&sre.SemanticTree.attrPred_("type","EMPTY")(a.childNodes[2])||sre.SemanticTree.attrPred_("type","EMPTY")(a.childNodes[3])&&sre.SemanticTree.attrPred_("type","EMPTY")(a.childNodes[4]))||sre.SemanticTree.attrPred_("role","CLOSE")(a)&&
+sre.SemanticTree.attrPred_("type","TENSOR")(a)||sre.SemanticTree.attrPred_("role","OPEN")(a)&&(sre.SemanticTree.attrPred_("type","SUBSCRIPT")(a)||sre.SemanticTree.attrPred_("type","SUPERSCRIPT")(a))?!1:b(a.childNodes[0]):!0};return b(a)};
+sre.SemanticTree.rewriteFencedNode_=function(a){var b=a.contentNodes[1],c=sre.SemanticTree.rewriteFence_(a,a.contentNodes[0]);a.contentNodes[0]=c.fence;c=sre.SemanticTree.rewriteFence_(c.node,b);a.contentNodes[1]=c.fence;a.contentNodes[0].parent=a;a.contentNodes[1].parent=a;c.node.parent=null;return c.node};
+sre.SemanticTree.rewriteFence_=function(a,b){if(!b.embellished)return{node:a,fence:b};var c=b.childNodes[0],d=sre.SemanticTree.rewriteFence_(a,c);if(sre.SemanticTree.attrPred_("type","SUPERSCRIPT")(b)||sre.SemanticTree.attrPred_("type","SUBSCRIPT")(b)||sre.SemanticTree.attrPred_("type","TENSOR")(b))return sre.SemanticTree.attrPred_("role","SUBSUP")(b)||(b.role=a.role),c!==d.node&&(b.replaceChild_(c,d.node),c.parent=a),sre.SemanticTree.propagateFencePointer_(b,c),{node:b,fence:d.fence};b.replaceChild_(c,
+d.fence);b.mathmlTree&&-1===b.mathml.indexOf(b.mathmlTree)&&b.mathml.push(b.mathmlTree);return{node:d.node,fence:b}};sre.SemanticTree.propagateFencePointer_=function(a,b){a.fencePointer=b.fencePointer||b.id.toString();a.embellished=null};sre.SemanticTree.prototype.displayTree=function(){this.root.displayTree(0)};
+sre.SemanticTree.Node.prototype.displayTree=function(a){a++;var b=Array(a).join("  ");console.log(b+this.toString());console.log(b+"MathmlTree:");console.log(b+this.mathmlTreeString_());console.log(b+"MathML:");for(var c=0,d;d=this.mathml[c];c++)console.log(b+d.toString());console.log(b+"Begin Content");this.contentNodes.forEach(function(b){b.displayTree(a)});console.log(b+"End Content");console.log(b+"Begin Children");this.childNodes.forEach(function(b){b.displayTree(a)});console.log(b+"End Children")};
+sre.SemanticTree.Node.prototype.mathmlTreeString_=function(){return this.mathmlTree?this.mathmlTree.toString():"EMPTY"};sre.Semantic={};sre.Semantic.Font=sre.SemanticAttr.Font;sre.Semantic.Role=sre.SemanticAttr.Role;sre.Semantic.Type=sre.SemanticAttr.Type;sre.Semantic.getTree=function(a){return(new sre.SemanticTree(a)).xml()};sre.Semantic.getTreeFromString=function(a){a=sre.DomUtil.parseInput(a);return new sre.SemanticTree(a)};sre.EnrichMathml={};sre.EnrichMathml.Error=function(a){Error.call(this);this.message=a||"";this.name="MathML Enrichment Error"};goog.inherits(sre.EnrichMathml.Error,Error);sre.EnrichMathml.SETTINGS={collapsed:!0,implicit:!0};sre.EnrichMathml.ATTRIBUTE_PREFIX_="data-semantic-";
+sre.EnrichMathml.Attribute={ADDED:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"added",ALTERNATIVE:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"alternative",CHILDREN:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"children",COLLAPSED:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"collapsed",CONTENT:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"content",EMBELLISHED:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"embellished",FENCEPOINTER:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"fencepointer",FONT:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"font",ID:sre.EnrichMathml.ATTRIBUTE_PREFIX_+
+"id",OPERATOR:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"operator",PARENT:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"parent",PREFIX:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"prefix",ROLE:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"role",SPEECH:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"speech",TYPE:sre.EnrichMathml.ATTRIBUTE_PREFIX_+"type"};
+sre.EnrichMathml.enrich=function(a,b){var c=a.cloneNode(!0);sre.EnrichMathml.walkTree(b.root);sre.Debugger.getInstance().generateOutput(function(){sre.EnrichMathml.formattedOutput(c,a,b,!0);return[]});return a};
+sre.EnrichMathml.walkTree=function(a){var b=sre.EnrichCaseFactory.getCase(a);if(b)return b=b.getMathml(),sre.EnrichMathml.ascendNewNode(b);if(1===a.mathml.length)return sre.Debugger.getInstance().output("Walktree Case 0"),b=a.mathml[0],sre.EnrichMathml.setAttributes(b,a),sre.EnrichMathml.ascendNewNode(b);var b=a.contentNodes.map(sre.EnrichMathml.cloneContentNode),c=a.childNodes.map(sre.EnrichMathml.walkTree),c=sre.EnrichMathml.combineContentChildren_(a,b,c),b=a.mathmlTree;if(null===b)sre.Debugger.getInstance().output("Walktree Case 1"),
+b=sre.EnrichMathml.introduceNewLayer(c);else{var d=sre.EnrichMathml.attachedElement_(c);sre.Debugger.getInstance().output("Walktree Case 2");d?(sre.Debugger.getInstance().output("Walktree Case 2.1"),b=d.parentNode):(sre.Debugger.getInstance().output("Walktree Case 2.2"),b=sre.EnrichMathml.getInnerNode(b))}b=sre.EnrichMathml.rewriteMfenced(b);sre.EnrichMathml.mergeChildren_(b,c);sre.EnrichMathml.setAttributes(b,a);return sre.EnrichMathml.ascendNewNode(b)};
+sre.EnrichMathml.introduceNewLayer=function(a){var b=sre.EnrichMathml.mathmlLca_(a),c=b.node;b.valid&&sre.SemanticUtil.hasEmptyTag(c)||(sre.Debugger.getInstance().output("Walktree Case 1.1"),c=sre.DomUtil.createElement("mrow"),a[0]&&(sre.Debugger.getInstance().output("Walktree Case 1.1.1"),b=sre.EnrichMathml.attachedElement_(a),a=sre.EnrichMathml.childrenSubset_(b.parentNode,a),sre.DomUtil.replaceNode(b,c),a.forEach(function(a){c.appendChild(a)})));return c};
+sre.EnrichMathml.childrenSubset_=function(a,b){var c=sre.DomUtil.toArray(a.childNodes),d=Infinity,e=-Infinity;b.forEach(function(a){a=c.indexOf(a);-1!==a&&(d=Math.min(d,a),e=Math.max(e,a))});return c.slice(d,e+1)};sre.EnrichMathml.mergeChildren_=function(a,b){var c=a.childNodes;if(c.length)for(var d=0;b.length;)c[d]===b[0]||sre.EnrichMathml.functionApplication_(c[d],b[0])?(b.shift(),d++):c[d]&&-1===b.indexOf(c[d])?d++:(a.insertBefore(b[0],c[d]||null),b.shift());else b.forEach(function(b){a.appendChild(b)})};
+sre.EnrichMathml.functionApplication_=function(a,b){var c=sre.SemanticAttr.functionApplication();return a&&b&&a.textContent&&b.textContent&&a.textContent===c&&b.textContent===c&&"true"===b.getAttribute(sre.EnrichMathml.Attribute.ADDED)?(sre.DomUtil.replaceNode(a,b),!0):!1};
+sre.EnrichMathml.mathmlLca_=function(a){var b=sre.EnrichMathml.attachedElement_(a);if(!b)return{valid:!1,node:null};a=sre.EnrichMathml.attachedElement_(a.slice().reverse());if(b===a)return{valid:!0,node:b};var c=sre.EnrichMathml.pathToRoot_(b),b=sre.EnrichMathml.pathToRoot_(a,function(a){return-1!==c.indexOf(a)});a=b[0];var d=c.indexOf(a);return-1===d?{valid:!1,node:null}:{valid:sre.EnrichMathml.validLca_(c[d+1],b[1]),node:a}};
+sre.EnrichMathml.attachedElement_=function(a){for(var b=0,c=null;!c&&b<a.length;)a[b].parentNode&&(c=a[b]),b++;return c};sre.EnrichMathml.pathToRoot_=function(a,b){for(var c=b||function(a){return!1},d=[a];!c(a)&&!sre.SemanticUtil.hasMathTag(a)&&a.parentNode;)a=sre.EnrichMathml.parentNode_(a),d.unshift(a);return d};sre.EnrichMathml.validLca_=function(a,b){return!(!a||!b||a.previousSibling||b.nextSibling)};
+sre.EnrichMathml.ascendNewNode=function(a){for(;!sre.SemanticUtil.hasMathTag(a)&&sre.EnrichMathml.unitChild_(a);)a=sre.EnrichMathml.parentNode_(a);return a};sre.EnrichMathml.unitChild_=function(a){var b=sre.EnrichMathml.parentNode_(a);return b&&sre.SemanticUtil.hasEmptyTag(b)?sre.DomUtil.toArray(b.childNodes).every(function(b){return b===a||sre.SemanticUtil.hasIgnoreTag(b)}):!1};sre.EnrichMathml.parentNode_=function(a){return a.parentNode};
+sre.EnrichMathml.simpleCollapseStructure=function(a){return"number"===typeof a};sre.EnrichMathml.interleaveIds=function(a,b){return sre.BaseUtil.interleaveLists(sre.EnrichMathml.collapsedLeafs(a),sre.EnrichMathml.collapsedLeafs(b))};sre.EnrichMathml.collapsedLeafs=function(a){var b=function(a){return sre.EnrichMathml.simpleCollapseStructure(a)?[a]:a.slice(1)};return Array.prototype.slice.call(arguments,0).reduce(function(a,d){return a.concat(b(d))},[])};
+sre.EnrichMathml.addCollapsedAttribute=function(a,b){var c=function(a){return sre.EnrichMathml.simpleCollapseStructure(a)?a.toString():"("+a.map(c).join(" ")+")"};a.setAttribute(sre.EnrichMathml.Attribute.COLLAPSED,c(b))};sre.EnrichMathml.cloneContentNode=function(a){if(a.mathml.length)return sre.EnrichMathml.walkTree(a);var b=sre.EnrichMathml.SETTINGS.implicit?sre.EnrichMathml.createInvisibleOperator_(a):sre.DomUtil.createElement("mrow");a.mathml=[b];return b};sre.EnrichMathml.makeIdList=function(a){return a.map(function(a){return a.id}).join(",")};
+sre.EnrichMathml.setAttributes=function(a,b){a.setAttribute(sre.EnrichMathml.Attribute.TYPE,b.type);a.setAttribute(sre.EnrichMathml.Attribute.ROLE,b.role);b.font!=sre.SemanticAttr.Font.UNKNOWN&&a.setAttribute(sre.EnrichMathml.Attribute.FONT,b.font);a.setAttribute(sre.EnrichMathml.Attribute.ID,b.id);b.childNodes.length&&a.setAttribute(sre.EnrichMathml.Attribute.CHILDREN,sre.EnrichMathml.makeIdList(b.childNodes));b.contentNodes.length&&a.setAttribute(sre.EnrichMathml.Attribute.CONTENT,sre.EnrichMathml.makeIdList(b.contentNodes));
+b.parent&&a.setAttribute(sre.EnrichMathml.Attribute.PARENT,b.parent.id);b.embellished&&a.setAttribute(sre.EnrichMathml.Attribute.EMBELLISHED,b.embellished);b.fencePointer&&a.setAttribute(sre.EnrichMathml.Attribute.FENCEPOINTER,b.fencePointer)};
+sre.EnrichMathml.combineContentChildren_=function(a,b,c){sre.EnrichMathml.setOperatorAttribute_(a,b);switch(a.type){case sre.SemanticAttr.Type.RELSEQ:case sre.SemanticAttr.Type.INFIXOP:case sre.SemanticAttr.Type.MULTIREL:return sre.BaseUtil.interleaveLists(c,b);case sre.SemanticAttr.Type.PREFIXOP:return b.concat(c);case sre.SemanticAttr.Type.POSTFIXOP:return c.concat(b);case sre.SemanticAttr.Type.FENCED:return c.unshift(b[0]),c.push(b[1]),c;case sre.SemanticAttr.Type.PUNCTUATED:if(a.role===sre.SemanticAttr.Role.TEXT)return sre.BaseUtil.interleaveLists(c,
+b);for(var d=[],e=0,f=0,g,h;g=c[e],h=b[f];e++)g.getAttribute(sre.EnrichMathml.Attribute.ID)==h.getAttribute(sre.EnrichMathml.Attribute.ID)&&(f++,d.push(g));sre.EnrichMathml.setOperatorAttribute_(a,d);return c;case sre.SemanticAttr.Type.APPL:return[c[0],b[0],c[1]];case sre.SemanticAttr.Type.ROOT:return[c[1],c[0]];default:return c}};
+sre.EnrichMathml.rewriteMfenced=function(a){if("MFENCED"!==sre.SemanticUtil.tagName(a))return a;for(var b=sre.DomUtil.createElement("mrow"),c=0,d;d=a.attributes[c];c++)-1===["open","close","separators"].indexOf(d.name)&&b.setAttribute(d.name,d.value);sre.DomUtil.toArray(a.childNodes).forEach(function(a){b.appendChild(a)});sre.DomUtil.replaceNode(a,b);return b};
+sre.EnrichMathml.createInvisibleOperator_=function(a){var b=sre.DomUtil.createElement("mo"),c=sre.DomUtil.createTextNode(a.textContent);b.appendChild(c);sre.EnrichMathml.setAttributes(b,a);b.setAttribute(sre.EnrichMathml.Attribute.ADDED,"true");return b};sre.EnrichMathml.setOperatorAttribute_=function(a,b){var c=a.type+(a.textContent?","+a.textContent:"");b.forEach(function(a){sre.EnrichMathml.getInnerNode(a).setAttribute(sre.EnrichMathml.Attribute.OPERATOR,c)})};
+sre.EnrichMathml.getInnerNode=function(a){var b=sre.DomUtil.toArray(a.childNodes);if(!b)return a;for(var b=b.filter(function(a){return a.nodeType===sre.DomUtil.NodeType.ELEMENT_NODE&&!sre.SemanticUtil.hasIgnoreTag(a)}),c=[],d=0,e;e=b[d];d++)if(sre.SemanticUtil.hasEmptyTag(e)){var f=sre.EnrichMathml.getInnerNode(e);f&&f!==e&&c.push(f)}else c.push(e);return 1===c.length?c[0]:a};
+sre.EnrichMathml.formattedOutput=function(a,b,c,d){d=d||!1;sre.EnrichMathml.formattedOutput_(a,"Original MathML",d);sre.EnrichMathml.formattedOutput_(c,"Semantic Tree",d);sre.EnrichMathml.formattedOutput_(b,"Semantically enriched MathML",d)};sre.EnrichMathml.formattedOutput_=function(a,b,c){a=sre.DomUtil.formatXml(a.toString());c?console.log(b+":\n```html\n"+sre.EnrichMathml.removeAttributePrefix(a)+"\n```\n"):console.log(a)};
+sre.EnrichMathml.removeAttributePrefix=function(a){return a.toString().replace(new RegExp(sre.EnrichMathml.ATTRIBUTE_PREFIX_,"g"),"")};sre.EnrichMathml.printNodeList__=function(a,b){console.log(a);sre.DomUtil.toArray(b).forEach(function(a){console.log(a.toString())});console.log("<<<<<<<<<<<<<<<<<")};sre.CaseDoubleScript=function(a){sre.AbstractEnrichCase.call(this,a);this.mml=a.mathmlTree};goog.inherits(sre.CaseDoubleScript,sre.AbstractEnrichCase);sre.CaseDoubleScript.test=function(a){if(!a.mathmlTree)return!1;var b=sre.SemanticUtil.tagName(a.mathmlTree);return"MSUBSUP"===b&&a.type===sre.SemanticAttr.Type.SUPERSCRIPT||"MUNDEROVER"===b&&a.type===sre.SemanticAttr.Type.OVERSCORE};
+sre.CaseDoubleScript.prototype.getMathml=function(){var a=this.semantic.childNodes[1],b=this.semantic.childNodes[0],c=b.childNodes[0],d=b.childNodes[1],e=sre.EnrichMathml.walkTree(a),f=sre.EnrichMathml.walkTree(c),g=sre.EnrichMathml.walkTree(d);sre.EnrichMathml.setAttributes(this.mml,this.semantic);this.mml.setAttribute(sre.EnrichMathml.Attribute.CHILDREN,sre.EnrichMathml.makeIdList([c,d,a]));[f,g,e].forEach(goog.bind(function(a){sre.EnrichMathml.getInnerNode(a).setAttribute(sre.EnrichMathml.Attribute.PARENT,
+this.mml.getAttribute(sre.EnrichMathml.Attribute.ID))},this));this.mml.setAttribute(sre.EnrichMathml.Attribute.TYPE,b.role);sre.EnrichMathml.addCollapsedAttribute(this.mml,[this.semantic.id,[b.id,c.id,d.id],a.id]);return this.mml};sre.CaseMultiindex=function(a){sre.AbstractEnrichCase.call(this,a);this.mml=a.mathmlTree};goog.inherits(sre.CaseMultiindex,sre.AbstractEnrichCase);
+sre.CaseMultiindex.prototype.completeMultiscript=function(a,b){var c=sre.DomUtil.toArray(this.mml.childNodes).slice(1),d=0,e=goog.bind(function(a){for(var b=0,e;e=a[b];b++){var f=c[d];if(f&&e==sre.EnrichMathml.getInnerNode(f).getAttribute(sre.EnrichMathml.Attribute.ID))sre.EnrichMathml.getInnerNode(f).setAttribute(sre.EnrichMathml.Attribute.PARENT,this.semantic.id),d++;else{var k=this.semantic.querySelectorAll(function(a){return a.id===e});this.mml.insertBefore(sre.CaseMultiindex.createNone_(k[0]),
+f||null)}}},this);e(a);c[d]&&"MPRESCRIPTS"!==sre.SemanticUtil.tagName(c[d])?this.mml.insertBefore(c[d],sre.DomUtil.createElement("mprescripts")):d++;e(b)};sre.CaseMultiindex.createNone_=function(a){var b=sre.DomUtil.createElement("none");a&&sre.EnrichMathml.setAttributes(b,a);b.setAttribute(sre.EnrichMathml.Attribute.ADDED,"true");return b};
+sre.CaseMultiindex.multiscriptIndex=function(a){if(a.type===sre.SemanticAttr.Type.PUNCTUATED&&a.contentNodes[0].role===sre.SemanticAttr.Role.DUMMY){for(var b=a.role,c=a.parent.id,d=[a.id],e=0,f;f=a.childNodes[e];e++){var g=sre.EnrichMathml.walkTree(f),g=sre.EnrichMathml.getInnerNode(g);g.setAttribute(sre.EnrichMathml.Attribute.PARENT,c);g.setAttribute(sre.EnrichMathml.Attribute.ROLE,b);d.push(f.id)}return d}sre.EnrichMathml.walkTree(a);return a.id};sre.CaseMultiscripts=function(a){sre.CaseMultiindex.call(this,a)};goog.inherits(sre.CaseMultiscripts,sre.CaseMultiindex);sre.CaseMultiscripts.test=function(a){return a.mathmlTree?"MMULTISCRIPTS"===sre.SemanticUtil.tagName(a.mathmlTree)&&(a.type===sre.SemanticAttr.Type.SUPERSCRIPT||a.type===sre.SemanticAttr.Type.SUBSCRIPT):!1};
+sre.CaseMultiscripts.prototype.getMathml=function(){sre.EnrichMathml.setAttributes(this.mml,this.semantic);if(this.semantic.childNodes[0]&&this.semantic.childNodes[0].role===sre.SemanticAttr.Role.SUBSUP){var a=this.semantic.childNodes[0],b=a.childNodes[0],c=sre.CaseMultiindex.multiscriptIndex(this.semantic.childNodes[1]),d=sre.CaseMultiindex.multiscriptIndex(a.childNodes[1]),e=[this.semantic.id,[a.id,b.id,d],c];sre.EnrichMathml.addCollapsedAttribute(this.mml,e);this.mml.setAttribute(sre.EnrichMathml.Attribute.TYPE,
+a.role);this.completeMultiscript(sre.EnrichMathml.interleaveIds(d,c),[])}else b=this.semantic.childNodes[0],c=sre.CaseMultiindex.multiscriptIndex(this.semantic.childNodes[1]),sre.EnrichMathml.simpleCollapseStructure(c)||(e=[this.semantic.id,b.id,c],sre.EnrichMathml.addCollapsedAttribute(this.mml,e));a=sre.EnrichMathml.collapsedLeafs(d||[],c);c=sre.EnrichMathml.walkTree(b);sre.EnrichMathml.getInnerNode(c).setAttribute(sre.EnrichMathml.Attribute.PARENT,this.semantic.id);a.unshift(b.id);this.mml.setAttribute(sre.EnrichMathml.Attribute.CHILDREN,
+a.join(","));return this.mml};sre.CaseEmbellished=function(a){sre.AbstractEnrichCase.call(this,a);this.ofenceMml=this.ofence=this.fencedMml=this.fenced=null;this.ofenceMap={};this.cfenceMml=this.cfence=null;this.cfenceMap={};this.parentCleanup=[]};goog.inherits(sre.CaseEmbellished,sre.AbstractEnrichCase);sre.CaseEmbellished.test=function(a){return a.mathmlTree&&a.fencePointer};sre.CaseEmbellished.prototype.getMathml=function(){this.getFenced_();this.fencedMml=sre.EnrichMathml.walkTree(this.fenced);this.getFencesMml_();return this.rewrite_()};
+sre.CaseEmbellished.prototype.getFenced_=function(){for(var a=this.semantic;a.type!==sre.SemanticAttr.Type.FENCED;)a=a.childNodes[0];this.fenced=a.childNodes[0];this.ofence=a.contentNodes[0];this.cfence=a.contentNodes[1];sre.CaseEmbellished.fencedMap_(this.ofence,this.ofenceMap);sre.CaseEmbellished.fencedMap_(this.cfence,this.cfenceMap)};sre.CaseEmbellished.fencedMap_=function(a,b){b[a.id]=a.mathmlTree;a.embellished&&sre.CaseEmbellished.fencedMap_(a.childNodes[0],b)};
+sre.CaseEmbellished.prototype.getFencesMml_=function(){for(var a=this.semantic,b=Object.keys(this.ofenceMap),c=Object.keys(this.cfenceMap);!(this.ofenceMml&&this.cfenceMml||a===this.fenced);)-1===b.indexOf(a.fencePointer)||this.ofenceMml||(this.ofenceMml=a.mathmlTree),-1===c.indexOf(a.fencePointer)||this.cfenceMml||(this.cfenceMml=a.mathmlTree),a=a.childNodes[0];this.ofenceMml||(this.ofenceMml=this.ofence.mathmlTree);this.cfenceMml||(this.cfenceMml=this.cfence.mathmlTree);this.ofenceMml&&(this.ofenceMml=
+sre.EnrichMathml.ascendNewNode(this.ofenceMml));this.cfenceMml&&(this.cfenceMml=sre.EnrichMathml.ascendNewNode(this.cfenceMml))};
+sre.CaseEmbellished.prototype.rewrite_=function(){var a=this.semantic,b=null,c=this.introduceNewLayer_();for(sre.EnrichMathml.setAttributes(c,this.fenced.parent);a.type!==sre.SemanticAttr.Type.FENCED;){var d=a.mathmlTree,e=this.specialCase_(a,d);if(e)a=e;else{sre.EnrichMathml.setAttributes(d,a);for(var e=[],f=1,g;g=a.childNodes[f];f++)e.push(sre.EnrichMathml.walkTree(g));a=a.childNodes[0]}e=sre.DomUtil.createElement("dummy");f=c.parentNode;g=d.childNodes[0];sre.DomUtil.replaceNode(d,e);sre.DomUtil.replaceNode(c,
+d);sre.DomUtil.replaceNode(d.childNodes[0],c);sre.DomUtil.replaceNode(e,g);d.parentNode=f;c=d.childNodes[0];b||(b=d)}sre.EnrichMathml.walkTree(this.ofence);sre.EnrichMathml.walkTree(this.cfence);this.cleanupParents_();return b||c};
+sre.CaseEmbellished.prototype.specialCase_=function(a,b){var c=sre.SemanticUtil.tagName(b),d=null;if("MSUBSUP"===c)var d=a.childNodes[0],e=sre.CaseDoubleScript;else"MMULTISCRIPTS"!==c||a.type!==sre.SemanticAttr.Type.SUPERSCRIPT&&a.type!==sre.SemanticAttr.Type.SUBSCRIPT||(e=sre.CaseMultiscripts,d=a.childNodes[0]&&a.childNodes[0].role===sre.SemanticAttr.Role.SUBSUP?a.childNodes[0]:a);if(!d)return null;var c=d.childNodes[0],f=sre.CaseEmbellished.makeEmptyNode_(c.id);d.childNodes[0]=f;b=(new e(a)).getMathml();
+d.childNodes[0]=c;this.parentCleanup.push(b);return d.childNodes[0]};sre.CaseEmbellished.makeEmptyNode_=function(a){var b=sre.DomUtil.createElement("mrow");a=new sre.SemanticTree.Node(a);a.type=sre.SemanticAttr.Type.EMPTY;a.mathmlTree=b;return a};
+sre.CaseEmbellished.prototype.introduceNewLayer_=function(){var a=this.fullFence(this.ofenceMml),b=this.fullFence(this.cfenceMml),c=sre.DomUtil.createElement("mrow");sre.DomUtil.replaceNode(this.fencedMml,c);c.appendChild(this.fencedMml);c.insertBefore(a,this.fencedMml);c.appendChild(b);if(!c.parentNode){for(a=sre.DomUtil.createElement("mrow");0<c.childNodes.length;)a.appendChild(c.childNodes[0]);c.appendChild(a);c=a}return c};
+sre.CaseEmbellished.prototype.fullFence=function(a){for(var b=this.fencedMml.parentNode;a.parentNode&&a.parentNode!==b;)a=a.parentNode;return a};sre.CaseEmbellished.prototype.cleanupParents_=function(){this.parentCleanup.forEach(function(a){var b=a.childNodes[1].getAttribute(sre.EnrichMathml.Attribute.PARENT);a.childNodes[0].setAttribute(sre.EnrichMathml.Attribute.PARENT,b)})};sre.CaseLine=function(a){sre.AbstractEnrichCase.call(this,a);this.mml=a.mathmlTree};goog.inherits(sre.CaseLine,sre.AbstractEnrichCase);sre.CaseLine.test=function(a){return a.mathmlTree&&a.type===sre.SemanticAttr.Type.LINE};sre.CaseLine.prototype.getMathml=function(){this.semantic.childNodes.length&&sre.EnrichMathml.walkTree(this.semantic.childNodes[0]);sre.EnrichMathml.setAttributes(this.mml,this.semantic);return this.mml};sre.CaseTable=function(a){sre.AbstractEnrichCase.call(this,a);this.mml=a.mathmlTree};goog.inherits(sre.CaseTable,sre.AbstractEnrichCase);sre.CaseTable.test=function(a){return a.mathmlTree&&(a.type===sre.SemanticAttr.Type.MATRIX||a.type===sre.SemanticAttr.Type.VECTOR||a.type===sre.SemanticAttr.Type.CASES)};
+sre.CaseTable.prototype.getMathml=function(){var a=sre.EnrichMathml.cloneContentNode(this.semantic.contentNodes[0]),b=this.semantic.contentNodes[1]?sre.EnrichMathml.cloneContentNode(this.semantic.contentNodes[1]):null;this.semantic.childNodes.map(sre.EnrichMathml.walkTree);"MFENCED"===sre.SemanticUtil.tagName(this.mml)?(this.mml.insertBefore(a,this.mml.childNodes[0]||null),b&&this.mml.appendChild(b),this.mml=sre.EnrichMathml.rewriteMfenced(this.mml)):(a=[a,this.mml],b&&a.push(b),this.mml=sre.EnrichMathml.introduceNewLayer(a));
+sre.EnrichMathml.setAttributes(this.mml,this.semantic);return this.mml};sre.CaseTensor=function(a){sre.CaseMultiindex.call(this,a)};goog.inherits(sre.CaseTensor,sre.CaseMultiindex);sre.CaseTensor.test=function(a){return a.mathmlTree&&a.type===sre.SemanticAttr.Type.TENSOR};
+sre.CaseTensor.prototype.getMathml=function(){sre.EnrichMathml.walkTree(this.semantic.childNodes[0]);var a=sre.CaseMultiindex.multiscriptIndex(this.semantic.childNodes[1]),b=sre.CaseMultiindex.multiscriptIndex(this.semantic.childNodes[2]),c=sre.CaseMultiindex.multiscriptIndex(this.semantic.childNodes[3]),d=sre.CaseMultiindex.multiscriptIndex(this.semantic.childNodes[4]);sre.EnrichMathml.setAttributes(this.mml,this.semantic);var e=[this.semantic.id,a,b,c,d];e.every(sre.EnrichMathml.simpleCollapseStructure)||
+sre.EnrichMathml.addCollapsedAttribute(this.mml,e);e=sre.EnrichMathml.collapsedLeafs(a,b,c,d);e.unshift(this.semantic.childNodes[0].id);this.mml.setAttribute(sre.EnrichMathml.Attribute.CHILDREN,e.join(","));this.completeMultiscript(sre.EnrichMathml.interleaveIds(c,d),sre.EnrichMathml.interleaveIds(a,b));return this.mml};sre.EnrichCases=function(){};sre.EnrichCaseFactory.cases.push({test:sre.CaseEmbellished.test,constr:sre.CaseEmbellished},{test:sre.CaseDoubleScript.test,constr:sre.CaseDoubleScript},{test:sre.CaseTensor.test,constr:sre.CaseTensor},{test:sre.CaseMultiscripts.test,constr:sre.CaseMultiscripts},{test:sre.CaseLine.test,constr:sre.CaseLine},{test:sre.CaseTable.test,constr:sre.CaseTable});sre.Enrich={};sre.Enrich.semanticMathmlNode=function(a){a=a.cloneNode(!0);var b=new sre.SemanticTree(a);return sre.EnrichMathml.enrich(a,b)};sre.Enrich.semanticMathmlSync=function(a){a=sre.DomUtil.parseInput(a);return sre.Enrich.semanticMathmlNode(a)};sre.Enrich.semanticMathml=function(a,b){if(sre.Engine.isReady()){var c=sre.DomUtil.parseInput(a);b(sre.Enrich.semanticMathmlNode(c))}else setTimeout(function(){sre.Enrich.semanticMathml(a,b)},500)};
+sre.Enrich.testTranslation__=function(a){sre.Debugger.getInstance().init();a=sre.Enrich.semanticMathmlSync(sre.Enrich.prepareMmlString(a)).toString();sre.EnrichMathml.removeAttributePrefix(a);sre.Debugger.getInstance().exit();return a};sre.Enrich.prepareMmlString=function(a){a.match(/^<math/)||(a="<math>"+a);a.match(/\/math>$/)||(a+="</math>");return a};sre.ColorPicker=function(a,b){this.foreground=sre.ColorPicker.getChannelColor_(b,sre.ColorPicker.DEFAULT_FOREGROUND_);this.background=sre.ColorPicker.getChannelColor_(a,sre.ColorPicker.DEFAULT_BACKGROUND_)};sre.ColorPicker.DEFAULT_BACKGROUND_="blue";sre.ColorPicker.DEFAULT_FOREGROUND_="black";
+sre.ColorPicker.namedColors_={red:{red:255,green:0,blue:0},green:{red:0,green:255,blue:0},blue:{red:0,green:0,blue:255},yellow:{red:255,green:255,blue:0},cyan:{red:0,green:255,blue:255},magenta:{red:255,green:0,blue:255},white:{red:255,green:255,blue:255},black:{red:0,green:0,blue:0}};sre.ColorPicker.getChannelColor_=function(a,b){var c=a||{color:b},d=c.color?sre.ColorPicker.namedColors_[c.color]:c;d||(d=sre.ColorPicker.namedColors_[b]);d.alpha=c.hasOwnProperty("alpha")?c.alpha:1;return sre.ColorPicker.normalizeColor_(d)};
+sre.ColorPicker.normalizeColor_=function(a){var b=function(a){a=Math.max(a,0);a=Math.min(255,a);return Math.round(a)};a.red=b(a.red);a.green=b(a.green);a.blue=b(a.blue);a.alpha=Math.max(a.alpha,0);a.alpha=Math.min(1,a.alpha);return a};sre.ColorPicker.prototype.rgba=function(){var a=function(a){return"rgba("+a.red+","+a.green+","+a.blue+","+a.alpha+")"};return{background:a(this.background),foreground:a(this.foreground)}};
+sre.ColorPicker.prototype.rgb=function(){var a=function(a){return"rgb("+a.red+","+a.green+","+a.blue+")"};return{background:a(this.background),alphaback:this.background.alpha.toString(),foreground:a(this.foreground),alphafore:this.foreground.alpha.toString()}};
+sre.ColorPicker.prototype.hex=function(){var a=function(a){return"#"+sre.ColorPicker.toHex_(a.red)+sre.ColorPicker.toHex_(a.green)+sre.ColorPicker.toHex_(a.blue)};return{background:a(this.background),alphaback:this.background.alpha.toString(),foreground:a(this.foreground),alphafore:this.foreground.alpha.toString()}};sre.ColorPicker.toHex_=function(a){a=a.toString(16);return 1===a.length?"0"+a:a};sre.HighlighterInterface=function(){};sre.HighlighterInterface.prototype.highlight=function(a){};sre.HighlighterInterface.prototype.unhighlight=function(){};sre.HighlighterInterface.prototype.highlightAll=function(a){};sre.HighlighterInterface.prototype.unhighlightAll=function(){};sre.HighlighterInterface.prototype.setColor=function(a){};sre.HighlighterInterface.prototype.addEvents=function(a,b){};sre.AbstractHighlighter=function(){this.currentHighlights_=[];this.color=null;this.mactionName="";this.state_={}};sre.AbstractHighlighter.prototype.highlight=function(a){this.currentHighlights_.push(a.map(goog.bind(function(a){return this.highlightNode(a)},this)))};sre.AbstractHighlighter.prototype.highlightNode=goog.abstractMethod;sre.AbstractHighlighter.prototype.highlightAll=function(a){a=this.getMactionNodes(a);for(var b=0,c;c=a[b];b++)this.highlight([c])};
+sre.AbstractHighlighter.prototype.unhighlight=function(){var a=this.currentHighlights_.pop();a&&a.forEach(goog.bind(function(a){return this.unhighlightNode(a)},this))};sre.AbstractHighlighter.prototype.unhighlightNode=goog.abstractMethod;sre.AbstractHighlighter.prototype.unhighlightAll=function(){for(;0<this.currentHighlights_.length;)this.unhighlight()};sre.AbstractHighlighter.prototype.setColor=function(a){this.color=a};sre.AbstractHighlighter.prototype.colorString=function(){return this.color.rgba()};
+sre.AbstractHighlighter.prototype.addEvents=function(a,b){for(var c=this.getMactionNodes(a),d=0,e;e=c[d];d++)for(var f in b)e.addEventListener(f,b[f])};sre.AbstractHighlighter.prototype.getMactionNodes=function(a){return a.getElementsByClassName(this.mactionName)};sre.AbstractHighlighter.prototype.isMactionNode=function(a){return a.className&&a.className.match(new RegExp(this.mactionName))};sre.AbstractHighlighter.prototype.resetState=function(a){delete this.state_[a]};
+sre.AbstractHighlighter.prototype.setState=function(a,b){this.state_[a]=b};sre.AbstractHighlighter.prototype.getState=function(a){return this.state_[a]};sre.CssHighlighter=function(){sre.AbstractHighlighter.call(this);this.mactionName="mjx-maction"};goog.inherits(sre.CssHighlighter,sre.AbstractHighlighter);sre.CssHighlighter.prototype.highlightNode=function(a){var b={node:a,background:a.style.backgroundColor,foreground:a.style.color},c=this.colorString();a.style.backgroundColor=c.background;a.style.color=c.foreground;return b};sre.CssHighlighter.prototype.unhighlightNode=function(a){a.node.style.backgroundColor=a.background;a.node.style.color=a.foreground};sre.HtmlHighlighter=function(){sre.AbstractHighlighter.call(this);this.mactionName="maction"};goog.inherits(sre.HtmlHighlighter,sre.AbstractHighlighter);sre.HtmlHighlighter.prototype.setMode=function(a){this.mode=a};
+sre.HtmlHighlighter.prototype.highlightNode=function(a){var b={node:a,foreground:a.style.color,position:a.style.position},c=this.color.rgb();a.style.color=c.foreground;a.style.position="relative";var d=a.bbox;if(d&&d.w){var e=document.createElement("span"),f=parseFloat(a.style.paddingLeft||"0");e.style.backgroundColor=c.background;e.style.opacity=c.alphaback.toString();e.style.display="inline-block";e.style.height=d.h+d.d+.1+"em";e.style.verticalAlign=-d.d+"em";e.style.marginTop=e.style.marginBottom=
+"-0.05em";e.style.width=d.w+0+"em";e.style.marginLeft=f-0+"em";e.style.marginRight=-d.w-0-f+"em";a.parentNode.insertBefore(e,a);b.box=e}return b};sre.HtmlHighlighter.prototype.unhighlightNode=function(a){var b=a.node;b.style.color=a.foreground;b.style.position=a.position;a.box&&a.box.parentNode.removeChild(a.box)};sre.MmlHighlighter=function(){sre.AbstractHighlighter.call(this);this.mactionName="maction"};goog.inherits(sre.MmlHighlighter,sre.AbstractHighlighter);sre.MmlHighlighter.prototype.highlightNode=function(a){var b=a.getAttribute("style"),b=b+(";background-color: "+this.colorString().background),b=b+(";color: "+this.colorString().foreground);a.setAttribute("style",b);return{node:a}};
+sre.MmlHighlighter.prototype.unhighlightNode=function(a){var b=a.node.getAttribute("style"),b=b.replace(";background-color: "+this.colorString().background,""),b=b.replace(";color: "+this.colorString().foreground,"");a.node.setAttribute("style",b)};sre.MmlHighlighter.prototype.colorString=function(){return this.color.rgba()};sre.MmlHighlighter.prototype.getMactionNodes=function(a){return a.getElementsByTagName(this.mactionName)};sre.SvgHighlighter=function(){sre.AbstractHighlighter.call(this);this.mactionName="mjx-svg-maction"};goog.inherits(sre.SvgHighlighter,sre.AbstractHighlighter);
+sre.SvgHighlighter.prototype.highlightNode=function(a){if("svg"===a.tagName){var b={node:a,background:a.style.backgroundColor,foreground:a.style.color};a.style.backgroundColor=this.colorString().background;a.style.color=this.colorString().foreground;return b}var b=document.createElementNS("http://www.w3.org/2000/svg","rect"),c;if("use"===a.nodeName){var d=document.createElementNS("http://www.w3.org/2000/svg","g");a.parentNode.insertBefore(d,a);d.appendChild(a);c=d.getBBox();d.parentNode.replaceChild(a,
+d)}else c=a.getBBox();b.setAttribute("x",c.x-40);b.setAttribute("y",c.y-40);b.setAttribute("width",c.width+80);b.setAttribute("height",c.height+80);(c=a.getAttribute("transform"))&&b.setAttribute("transform",c);b.setAttribute("fill",this.colorString().background);a.parentNode.insertBefore(b,a);b={node:b,foreground:a.getAttribute("fill")};a.setAttribute("fill",this.colorString().foreground);return b};
+sre.SvgHighlighter.prototype.unhighlightNode=function(a){"background"in a?(a.node.style.backgroundColor=a.background,a.node.style.color=a.foreground):(a.foreground?a.node.nextSibling.setAttribute("fill",a.foreground):a.node.nextSibling.removeAttribute("fill"),a.node.parentNode.removeChild(a.node))};sre.SvgHighlighter.prototype.isMactionNode=function(a){return a.className.baseVal===this.mactionName};sre.HighlighterFactory={};sre.HighlighterFactory.highlighter=function(a,b,c){a=new sre.ColorPicker(a,b);c=sre.HighlighterFactory.highlighterMapping_["NativeMML"===c.renderer&&"Safari"===c.browser?"CommonHTML":c.renderer];if(!c)return null;c.setColor(a);return c};sre.HighlighterFactory.addEvents=function(a,b,c){(c=sre.HighlighterFactory.highlighterMapping_[c.renderer])&&c.addEvents(a,b)};
+sre.HighlighterFactory.highlighterMapping_={SVG:new sre.SvgHighlighter,NativeMML:new sre.MmlHighlighter,"HTML-CSS":new sre.HtmlHighlighter,CommonHTML:new sre.CssHighlighter};sre.SpeechRule=function(a,b,c,d){this.name=a;this.dynamicCstr=b;this.precondition=c;this.action=d};sre.SpeechRule.prototype.toString=function(){return this.name+" | "+sre.SpeechRule.stringifyCstr(this.dynamicCstr)+" | "+this.precondition.toString()+" ==> "+this.action.toString()};sre.SpeechRule.Type={NODE:"NODE",MULTI:"MULTI",TEXT:"TEXT",PERSONALITY:"PERSONALITY"};
+sre.SpeechRule.Type.fromString=function(a){switch(a){case "[n]":return sre.SpeechRule.Type.NODE;case "[m]":return sre.SpeechRule.Type.MULTI;case "[t]":return sre.SpeechRule.Type.TEXT;case "[p]":return sre.SpeechRule.Type.PERSONALITY;default:throw"Parse error: "+a;}};
+sre.SpeechRule.Type.toString=function(a){switch(a){case sre.SpeechRule.Type.NODE:return"[n]";case sre.SpeechRule.Type.MULTI:return"[m]";case sre.SpeechRule.Type.TEXT:return"[t]";case sre.SpeechRule.Type.PERSONALITY:return"[p]";default:throw"Unknown type error: "+a;}};sre.SpeechRule.Component=function(a){this.type=a.type;this.content=a.content};
+sre.SpeechRule.Component.fromString=function(a){var b={};b.type=sre.SpeechRule.Type.fromString(a.substring(0,3));a=a.slice(3).trim();if(!a)throw new sre.SpeechRule.OutputError("Missing content.");switch(b.type){case sre.SpeechRule.Type.TEXT:if('"'==a[0]){var c=sre.SpeechRule.splitString_(a,"\\(")[0].trim();if('"'!=c.slice(-1))throw new sre.SpeechRule.OutputError("Invalid string syntax.");b.content=c;a=a.slice(c.length).trim();-1==a.indexOf("(")&&(a="");break}case sre.SpeechRule.Type.NODE:case sre.SpeechRule.Type.MULTI:c=
+a.indexOf(" ("),-1==c?(b.content=a.trim(),a=""):(b.content=a.substring(0,c).trim(),a=a.slice(c).trim())}b=new sre.SpeechRule.Component(b);a&&b.addAttributes(a);return b};sre.SpeechRule.Component.prototype.toString=function(){var a;a=""+sre.SpeechRule.Type.toString(this.type);a+=this.content?" "+this.content:"";var b=this.getAttributes();0<b.length&&(a+=" ("+b.join(", ")+")");return a};
+sre.SpeechRule.Component.prototype.addAttribute=function(a){var b=a.indexOf(":");-1==b?this[a.trim()]="true":this[a.substring(0,b).trim()]=a.slice(b+1).trim()};sre.SpeechRule.Component.prototype.addAttributes=function(a){if("("!=a[0]||")"!=a.slice(-1))throw new sre.SpeechRule.OutputError("Invalid attribute expression: "+a);a=sre.SpeechRule.splitString_(a.slice(1,-1),",");for(var b=0;b<a.length;b++)this.addAttribute(a[b])};
+sre.SpeechRule.Component.prototype.getAttributes=function(){var a=[],b;for(b in this)"content"!=b&&"type"!=b&&"function"!=typeof this[b]&&a.push(b+":"+this[b]);return a};sre.SpeechRule.Action=function(a){this.components=a};sre.SpeechRule.Action.fromString=function(a){a=sre.SpeechRule.splitString_(a,";").filter(function(a){return a.match(/\S/)}).map(function(a){return a.trim()});for(var b=[],c=0;c<a.length;c++){var d=sre.SpeechRule.Component.fromString(a[c]);d&&b.push(d)}return new sre.SpeechRule.Action(b)};
+sre.SpeechRule.Action.prototype.toString=function(){return this.components.map(function(a){return a.toString()}).join("; ")};sre.SpeechRule.Precondition=function(a,b){this.query=a;this.constraints=b||[]};sre.SpeechRule.Precondition.prototype.toString=function(){var a=this.constraints.join(", ");return this.query+", "+a};
+sre.SpeechRule.splitString_=function(a,b){for(var c=[],d="";""!=a;){var e=a.search(b);if(-1==e){if(0!=(a.match(/"/g)||[]).length%2)throw new sre.SpeechRule.OutputError("Invalid string in expression: "+a);c.push(d+a);a=d=""}else if(0==(a.substring(0,e).match(/"/g)||[]).length%2)c.push(d+a.substring(0,e)),d="",a=a.substring(e+1);else{var f=a.substring(e).search('"');if(-1==f)throw new sre.SpeechRule.OutputError("Invalid string in expression: "+a);d+=a.substring(0,e+f+1);a=a.substring(e+f+1)}}d&&c.push(d);
+return c};sre.SpeechRule.DynamicCstrAttrib={STYLE:"style"};sre.SpeechRule.stringifyCstr=function(a){var b=[],c;for(c in a)b.push(a[c]);return b.join(".")};sre.SpeechRule.OutputError=function(a){Error.call(this);this.message=a||"";this.name="RuleError"};goog.inherits(sre.SpeechRule.OutputError,Error);sre.SpeechRuleEvaluator=goog.abstractMethod;sre.SpeechRuleEvaluator.prototype.evaluateDefault=goog.abstractMethod;sre.SpeechRuleFunctions=function(){};sre.SpeechRuleFunctions.Store_=function(a,b){this.prefix_=a;this.store_=b};sre.SpeechRuleFunctions.Store_.prototype.add=function(a,b){this.checkCustomFunctionSyntax_(a)&&(this.store_[a]=b)};sre.SpeechRuleFunctions.Store_.prototype.addStore=function(a){for(var b=Object.keys(a.store_),c=0,d;d=b[c];c++)this.add(d,a.store_[d])};sre.SpeechRuleFunctions.Store_.prototype.lookup=function(a){return this.store_[a]};
+sre.SpeechRuleFunctions.CustomQueries=function(){sre.SpeechRuleFunctions.Store_.call(this,"CQF",{})};goog.inherits(sre.SpeechRuleFunctions.CustomQueries,sre.SpeechRuleFunctions.Store_);sre.SpeechRuleFunctions.CustomStrings=function(){sre.SpeechRuleFunctions.Store_.call(this,"CSF",{})};goog.inherits(sre.SpeechRuleFunctions.CustomStrings,sre.SpeechRuleFunctions.Store_);sre.SpeechRuleFunctions.ContextFunctions=function(){sre.SpeechRuleFunctions.Store_.call(this,"CTXF",{})};
+goog.inherits(sre.SpeechRuleFunctions.ContextFunctions,sre.SpeechRuleFunctions.Store_);sre.SpeechRuleFunctions.Store_.prototype.checkCustomFunctionSyntax_=function(a){return a.match(new RegExp("^"+this.prefix_))?!0:(console.log("FunctionError: Invalid function name. Expected prefix "+this.prefix_),!1)};sre.SpeechRuleStore=goog.abstractMethod;sre.SpeechRuleStore.prototype.addRule=goog.abstractMethod;sre.SpeechRuleStore.prototype.deleteRule=goog.abstractMethod;sre.SpeechRuleStore.prototype.findRule=goog.abstractMethod;sre.SpeechRuleStore.prototype.findAllRules=goog.abstractMethod;sre.SpeechRuleStore.prototype.lookupRule=goog.abstractMethod;sre.SpeechRuleStore.prototype.defineRule=goog.abstractMethod;sre.BaseRuleStore=function(){this.customQueries=new sre.SpeechRuleFunctions.CustomQueries;this.customStrings=new sre.SpeechRuleFunctions.CustomStrings;this.contextFunctions=new sre.SpeechRuleFunctions.ContextFunctions;this.speechRules_=[];this.dynamicCstrAttribs=[sre.SpeechRule.DynamicCstrAttrib.STYLE];this.defaultTtsProps=[]};
+sre.BaseRuleStore.prototype.lookupRule=function(a,b){if(!a||a.nodeType!=sre.DomUtil.NodeType.ELEMENT_NODE&&a.nodeType!=sre.DomUtil.NodeType.TEXT_NODE)return null;var c=this.speechRules_.filter(goog.bind(function(c){return this.testDynamicConstraints(b,c)&&this.testPrecondition_(a,c)},this));return 0<c.length?this.pickMostConstraint_(b,c):null};
+sre.BaseRuleStore.prototype.defineRule=function(a,b,c,d,e){try{var f=sre.SpeechRule.Action.fromString(c),g=Array.prototype.slice.call(arguments,4),h=new sre.SpeechRule.Precondition(d,g),g={};g[sre.SpeechRule.DynamicCstrAttrib.STYLE]=b;var l=new sre.SpeechRule(a,g,h,f)}catch(k){if("RuleError"==k.name)return console.log("Rule Error ",d,"("+b+"):",k.message),null;throw k;}this.addRule(l);return l};sre.BaseRuleStore.prototype.addRule=function(a){this.speechRules_.unshift(a)};
+sre.BaseRuleStore.prototype.deleteRule=function(a){a=this.speechRules_.indexOf(a);-1!=a&&this.speechRules_.splice(a,1)};sre.BaseRuleStore.prototype.findRule=function(a){for(var b=0,c;c=this.speechRules_[b];b++)if(a(c))return c;return null};sre.BaseRuleStore.prototype.findAllRules=function(a){return this.speechRules_.filter(a)};sre.BaseRuleStore.prototype.evaluateDefault=function(a){return[new sre.AuditoryDescription({text:a.textContent})]};
+sre.BaseRuleStore.prototype.debugSpeechRule=function(a,b){var c=a.precondition,d=this.applyQuery(b,c.query);sre.Debugger.getInstance().output(c.query,d?d.toString():d);c.constraints.forEach(goog.bind(function(a){sre.Debugger.getInstance().output(a,this.applyConstraint(b,a))},this))};sre.BaseRuleStore.prototype.initialize=goog.abstractMethod;
+sre.BaseRuleStore.prototype.removeDuplicates=function(a){for(var b=this.speechRules_.length-1,c;c=this.speechRules_[b];b--)c!=a&&sre.BaseRuleStore.compareDynamicConstraints_(c.dynamicCstr,a.dynamicCstr)&&sre.BaseRuleStore.comparePreconditions_(c,a)&&this.speechRules_.splice(b,1)};sre.BaseRuleStore.prototype.applyCustomQuery=function(a,b){var c=this.customQueries.lookup(b);return c?c(a):null};
+sre.BaseRuleStore.prototype.applySelector=function(a,b){return this.applyCustomQuery(a,b)||sre.XpathUtil.evalXPath(b,a)};sre.BaseRuleStore.prototype.applyQuery=function(a,b){var c=this.applySelector(a,b);return 0<c.length?c[0]:null};sre.BaseRuleStore.prototype.applyConstraint=function(a,b){return!!this.applyQuery(a,b)||sre.XpathUtil.evaluateBoolean(b,a)};
+sre.BaseRuleStore.prototype.testDynamicConstraints=function(a,b){return sre.Engine.getInstance().strict?this.equalDynamicConstraints(a,b):Object.keys(a).every(function(c){return a[c]==b.dynamicCstr[c]||"short"==b.dynamicCstr[c]||"default"==b.dynamicCstr[c]})};sre.BaseRuleStore.prototype.equalDynamicConstraints=function(a,b){return Object.keys(a).every(function(c){return a[c]==b.dynamicCstr[c]})};
+sre.BaseRuleStore.prototype.getDynamicConstraintValues=function(){for(var a={},b=0,c;c=this.speechRules_[b];b++)for(var d in c.dynamicCstr){var e=[c.dynamicCstr[d]];a[d]=a[d]?sre.BaseUtil.union(a[d],e):e}return a};sre.BaseRuleStore.prototype.countMatchingDynamicConstraintValues_=function(a,b){for(var c=0,d=0,e;e=this.dynamicCstrAttribs[d];d++)if(a[e]===b.dynamicCstr[e])c++;else break;return c};
+sre.BaseRuleStore.prototype.pickMostConstraint_=function(a,b){b.sort(goog.bind(function(b,d){var c=this.countMatchingDynamicConstraintValues_(a,b),f=this.countMatchingDynamicConstraintValues_(a,d);return c>f?-1:f>c?1:d.precondition.constraints.length-b.precondition.constraints.length},this));sre.Debugger.getInstance().generateOutput(goog.bind(function(){return b.map(function(a){return a.name+"("+sre.SpeechRule.stringifyCstr(a.dynamicCstr)+")"})},this));return b[0]};
+sre.BaseRuleStore.prototype.testPrecondition_=function(a,b){var c=b.precondition;this.applyQuery(a,c.query);return this.applyQuery(a,c.query)===a&&c.constraints.every(goog.bind(function(b){return this.applyConstraint(a,b)},this))};sre.BaseRuleStore.compareDynamicConstraints_=function(a,b){if(Object.keys(a).length!=Object.keys(b).length)return!1;for(var c in a)if(!b[c]||a[c]!==b[c])return!1;return!0};
+sre.BaseRuleStore.compareStaticConstraints_=function(a,b){if(a.length!=b.length)return!1;for(var c=0,d;d=a[c];c++)if(-1==b.indexOf(d))return!1;return!0};sre.BaseRuleStore.comparePreconditions_=function(a,b){var c=a.precondition,d=b.precondition;return c.query!=d.query?!1:sre.BaseRuleStore.compareStaticConstraints_(c.constraints,d.constraints)};sre.BaseRuleStore.prototype.getSpeechRules=function(){return this.speechRules_};sre.BaseRuleStore.prototype.setSpeechRules=function(a){this.speechRules_=a};sre.MathStore=function(){sre.BaseRuleStore.call(this);this.dynamicCstrAttribs=[sre.SpeechRule.DynamicCstrAttrib.DOMAIN,sre.SpeechRule.DynamicCstrAttrib.STYLE];this.defaultTtsProps=[sre.Engine.personalityProps.PITCH,sre.Engine.personalityProps.RATE];this.initialized=!1;this.initializer=[]};goog.inherits(sre.MathStore,sre.BaseRuleStore);sre.SpeechRule.DynamicCstrAttrib.DOMAIN="domain";
+sre.MathStore.prototype.initialize=function(){if(!this.initialized){for(var a=0,b;b=this.initializer[a];a++)b();this.initialized=!0}};sre.MathStore.prototype.defineRule=function(a,b,c,d,e){var f=this.parseDynamicConstraint(b),g=Array.prototype.slice.call(arguments,4),g=sre.MathStore.superClass_.defineRule.apply(this,[a,f[sre.SpeechRule.DynamicCstrAttrib.STYLE],c,d].concat(g));g.dynamicCstr=f;this.removeDuplicates(g);return g};
+sre.MathStore.prototype.parseDynamicConstraint=function(a){var b=a.split(".");if(!b[0]||!b[1])throw new sre.SpeechRule.OutputError("Invalid domain assignment:"+a);return sre.MathStore.createDynamicConstraint(b[0],b[1])};sre.MathStore.createDynamicConstraint=function(a,b){var c={};c[sre.SpeechRule.DynamicCstrAttrib.DOMAIN]=a;c[sre.SpeechRule.DynamicCstrAttrib.STYLE]=b;return c};
+sre.MathStore.prototype.defineUniqueRuleAlias=function(a,b,c,d){var e=this.parseDynamicConstraint(b),f=this.findRule(goog.bind(function(b){return b.name==a&&this.equalDynamicConstraints(e,b)},this));if(!f)throw new sre.SpeechRule.OutputError("Rule named "+a+" with style "+b+" does not exist.");this.addAlias_(f,c,Array.prototype.slice.call(arguments,3))};
+sre.MathStore.prototype.defineRuleAlias=function(a,b,c){var d=this.findRule(function(b){return b.name==a});if(!d)throw new sre.SpeechRule.OutputError("Rule with named "+a+" does not exist.");this.addAlias_(d,b,Array.prototype.slice.call(arguments,2))};
+sre.MathStore.prototype.defineRulesAlias=function(a,b,c){var d=this.findAllRules(function(b){return b.name==a});if(0==d.length)throw new sre.SpeechRule.OutputError("Rule with name "+a+" does not exist.");var e=Array.prototype.slice.call(arguments,2);d.forEach(goog.bind(function(a){this.addAlias_(a,b,e)},this))};sre.MathStore.prototype.addAlias_=function(a,b,c){b=new sre.SpeechRule.Precondition(b,c);b=new sre.SpeechRule(a.name,a.dynamicCstr,b,a.action);b.name=a.name;this.addRule(b)};
+sre.MathStore.prototype.defineSpecialisedRule=function(a,b,c,d){var e=this.parseDynamicConstraint(b),f=this.findRule(goog.bind(function(b){return b.name==a&&this.equalDynamicConstraints(e,b)},this));if(!f)throw new sre.SpeechRule.OutputError("Rule named "+a+" with style "+b+" does not exist.");b=this.parseDynamicConstraint(c);d=d?sre.SpeechRule.Action.fromString(d):f.action;f=new sre.SpeechRule(f.name,b,f.precondition,d);this.addRule(f)};sre.MathStore.prototype.evaluateDefault=function(a){return this.evaluateString_(a.textContent)};
+sre.MathStore.prototype.evaluateString_=function(a){var b=[];if(a.match(/^\s+$/))return b;a=sre.BaseUtil.removeEmpty(a.replace(/\s/g," ").split(" "));for(var c=0,d;d=a[c];c++)if(1==d.length)b.push(this.evaluate_(d));else if(d.match(/^[a-zA-Z]+$/))b.push(this.evaluate_(d));else for(;d;){var e=d.match(/^((\d{1,3})(?=,)(,\d{3})*(\.\d+)?)|^\d*\.\d+|^\d+/),f=d.match(/^[a-zA-Z]+/);e?(b.push(this.evaluate_(e[0])),d=d.substring(e[0].length)):f?(b.push(this.evaluate_(f[0])),d=d.substring(f[0].length)):(e=
+d[0].charCodeAt(0),55296<=e&&56319>=e&&1<d.length&&!isNaN(d.charCodeAt(1))?(b.push(this.evaluate_(d.slice(0,2))),d=d.substring(2)):(b.push(this.evaluate_(d[0])),d=d.substring(1)))}return b};sre.MathStore.prototype.evaluate_=function(a){return new sre.AuditoryDescription({text:a,preprocess:!0,correction:sre.SpeechRuleEngine.getInstance().getGlobalParameter("remove")||""})};sre.MathSimpleStore=function(){sre.MathStore.call(this)};goog.inherits(sre.MathSimpleStore,sre.MathStore);sre.MathSimpleStore.prototype.defineRulesFromMappings=function(a,b,c){for(var d in c)for(var e in c[d])this.defineRule(a,d+"."+e,'[t] "'+c[d][e]+'"',"self::text()",'"'===b?"self::text() = '"+b+"'":'self::text() = "'+b+'"')};sre.MathCompoundStore=function(){this.subStores_={}};goog.addSingletonGetter(sre.MathCompoundStore);
+sre.MathCompoundStore.prototype.defineRules=function(a,b,c){var d=new sre.MathSimpleStore;d.defineRulesFromMappings(a,b,c);this.subStores_[b]=d};sre.MathCompoundStore.prototype.addSymbolRules=function(a){var b=sre.MathSimpleStore.parseUnicode_(a.key);this.defineRules(a.key,b,a.mappings)};sre.MathCompoundStore.prototype.addFunctionRules=function(a){var b=a.names;a=a.mappings;for(var c=0,d;d=b[c];c++)this.defineRules(d,d,a)};
+sre.MathCompoundStore.prototype.addUnitRules=function(a){var b=a.names;b&&(a.names=b.map(function(a){return a+":unit"}));this.addFunctionRules(a)};sre.MathCompoundStore.prototype.lookupRule=function(a,b){var c=this.subStores_[a.textContent];return c?c.lookupRule(a,b):null};
+sre.MathCompoundStore.prototype.lookupString=function(a,b){var c=sre.XpathUtil.currentDocument?sre.XpathUtil.currentDocument.createTextNode(a):sre.DomUtil.createTextNode(a);return(c=this.lookupRule(c,b))?c.action.components.map(function(a){return a.content.slice(1,-1)}).join(" "):""};
+sre.MathCompoundStore.prototype.getDynamicConstraintValues=function(){var a={},b;for(b in this.subStores_){var c=this.subStores_[b].getDynamicConstraintValues(),d;for(d in c){var e=a[d];a[d]=e?sre.BaseUtil.union(e,c[d]):c[d]}}return a};sre.MathSimpleStore.parseUnicode_=function(a){a=parseInt(a,16);if(65536>a)return String.fromCharCode(a);a-=65536;return String.fromCharCode((a>>10)+55296,(a&1023)+56320)};sre.MathMap=function(){this.store=sre.MathCompoundStore.getInstance();this.allDomains=[];this.allStyles=[];this.retrieveMaps();this.getDynamicConstraintValues()};goog.addSingletonGetter(sre.MathMap);sre.MathMap.toFetch_=0;sre.Engine.registerTest(function(){return sre.MathMap.getInstance()&&!sre.MathMap.toFetch_});sre.MathMap.prototype.stringify=function(){return JSON.stringify(this)};sre.MathMap.SYMBOLS_PATH_="symbols";sre.MathMap.FUNCTIONS_PATH_="functions";sre.MathMap.UNITS_PATH_="units";
+sre.MathMap.SYMBOLS_FILES_="greek-capital.json greek-small.json greek-scripts.json greek-mathfonts.json greek-symbols.json hebrew_letters.json latin-lower-double-accent.json latin-lower-normal.json latin-lower-phonetic.json latin-lower-single-accent.json latin-rest.json latin-upper-double-accent.json latin-upper-normal.json latin-upper-single-accent.json latin-mathfonts.json math_angles.json math_arrows.json math_characters.json math_delimiters.json math_digits.json math_geometry.json math_harpoons.json math_non_characters.json math_symbols.json math_whitespace.json other_stars.json".split(" ");
+sre.MathMap.FUNCTIONS_FILES_=["algebra.json","elementary.json","hyperbolic.json","trigonometry.json"];sre.MathMap.UNITS_FILES_="energy.json length.json memory.json other.json speed.json temperature.json time.json volume.json weight.json".split(" ");
+sre.MathMap.retrieveFiles=function(a,b,c){b=sre.BaseUtil.makePath(sre.SystemExternal.jsonPath+b);switch(sre.Engine.getInstance().mode){case sre.Engine.Mode.ASYNC:sre.MathMap.toFetch_+=a.length;for(var d=0,e;e=a[d];d++)sre.MathMap.fromFile_(b+e,function(a,b){sre.MathMap.toFetch_--;a||JSON.parse(b).forEach(function(a){c(a)})});break;case sre.Engine.Mode.HTTP:var f=sre.Engine.getInstance().isIE;sre.MathMap.toFetch_+=a.length;for(d=0;e=a[d];d++)f?sre.MathMap.getJsonIE_(e,c):sre.MathMap.getJsonAjax_(b+
+e,c);break;default:sre.MathMap.parseFiles(a.map(function(a){return b+a})).forEach(function(a){c(a)})}};
+sre.MathMap.prototype.retrieveMaps=function(){sre.MathMap.retrieveFiles(sre.MathMap.FUNCTIONS_FILES_,sre.MathMap.FUNCTIONS_PATH_,goog.bind(this.store.addFunctionRules,this.store));sre.MathMap.retrieveFiles(sre.MathMap.SYMBOLS_FILES_,sre.MathMap.SYMBOLS_PATH_,goog.bind(this.store.addSymbolRules,this.store));sre.MathMap.retrieveFiles(sre.MathMap.UNITS_FILES_,sre.MathMap.UNITS_PATH_,goog.bind(this.store.addUnitRules,this.store))};
+sre.MathMap.getJsonIE_=function(a,b,c){var d=c||1;sre.BrowserUtil.mapsForIE?((c=sre.BrowserUtil.mapsForIE[a])&&c.forEach(function(a){b(a)}),sre.MathMap.toFetch_--):5>=d?setTimeout(function(){sre.MathMap.getJsonIE_(a,b,d++)},300):sre.MathMap.toFetch_--};sre.MathMap.fromFile_=function(a,b){return sre.SystemExternal.fs.readFile(a,"utf8",b)};sre.MathMap.loadFile=function(a){try{return sre.MathMap.readJSON_(a)}catch(b){console.log("Unable to load file: "+a+", error: "+b)}};sre.MathMap.loadFiles=function(a){return a.map(sre.MathMap.loadFile)};
+sre.MathMap.parseFiles=function(a){a=sre.MathMap.loadFiles(a);return[].concat.apply([],a.map(function(a){return JSON.parse(a)}))};sre.MathMap.readJSON_=function(a){return sre.SystemExternal.fs.readFileSync(a)};sre.MathMap.getJsonAjax_=function(a,b){var c=new XMLHttpRequest;c.onreadystatechange=function(){4===c.readyState&&(sre.MathMap.toFetch_--,200===c.status&&JSON.parse(c.responseText).forEach(function(a){b(a)}))};c.open("GET",a,!0);c.send()};
+sre.MathMap.prototype.getDynamicConstraintValues=function(){if(sre.MathMap.toFetch_)setTimeout(goog.bind(this.getDynamicConstraintValues,this),300);else{var a=this.store.getDynamicConstraintValues();this.allDomains=a.domain;this.allStyles=a.style}};sre.AuditoryDescription=function(a){this.context=a.context?a.context:"";this.text=a.text?a.text:"";this.userValue=a.userValue?a.userValue:"";this.annotation=a.annotation?a.annotation:"";this.correction=a.correction?a.correction:"";this.personality=a.personality;this.preprocess=!!a.preprocess};sre.AuditoryDescription.prototype.isEmpty=function(){return 0==this.context.length&&0==this.text.length&&0==this.userValue.length&&0==this.annotation.length};
+sre.AuditoryDescription.prototype.toString=function(){return'AuditoryDescription(context="'+this.context+'"  text="'+this.text+'"  userValue="'+this.userValue+'"  annotation="'+this.annotation+'")'};sre.AuditoryDescription.prototype.descriptionString=function(){return this.context?this.context+" "+this.text:this.text};sre.AuditoryDescription.prototype.equals=function(a){return this.context==a.context&&this.text==a.text&&this.userValue==a.userValue&&this.annotation==a.annotation};
+sre.AuditoryDescription.speechString=function(a,b){var c=""===b?"":b||" ";sre.AuditoryDescription.preprocessDescriptionList(a);return sre.AuditoryDescription.toString_(a,c)};sre.AuditoryDescription.toString_=function(a,b){return sre.Engine.getInstance().ssml?sre.AuditoryDescription.toSsmlString_(a,b):sre.AuditoryDescription.toSimpleString_(a,b)};
+sre.AuditoryDescription.toSsmlString_=function(a,b){return sre.BaseUtil.removeEmpty(a.map(function(a){return a.personality&&a.personality.PAUSE?'<break time="'+a.personality.PAUSE+'ms"/>':a.descriptionString()})).join(b)};sre.AuditoryDescription.toSimpleString_=function(a,b){return sre.BaseUtil.removeEmpty(a.map(function(a){return a.descriptionString()})).join(b)};
+sre.AuditoryDescription.preprocessString_=function(a){if("mathspeak"==sre.Engine.getInstance().domain&&a.match(/^\d{1}$/))return a;var b=sre.MathStore.createDynamicConstraint(sre.Engine.getInstance().domain,sre.Engine.getInstance().style);return sre.MathMap.getInstance().store.lookupString(a,b)||a};sre.AuditoryDescription.processCorrections_=function(a,b){if(!b||!a)return a;var c=b.split(/ |-/),c=new RegExp("^"+c.join("( |-)")+"( |-)");return a.replace(c,"")};
+sre.AuditoryDescription.preprocessDescription_=function(a){a.annotation&&(a.text+=":"+a.annotation,a.annotation="");a.preprocess&&(a.text=sre.AuditoryDescription.processCorrections_(sre.AuditoryDescription.preprocessString_(a.text),a.correction),a.preprocess=!1)};sre.AuditoryDescription.preprocessDescriptionList=function(a){for(var b=0,c;c=a[b];b++)sre.AuditoryDescription.preprocessDescription_(c)};sre.MathspeakUtil={};sre.MathspeakUtil.spaceoutText=function(a){return a.textContent.split("").join(" ")};sre.MathspeakUtil.spaceoutNumber=function(a){a=a.textContent.split("");for(var b=[],c=new sre.SystemExternal.xmldom.DOMParser,d=0,e;e=a[d];d++){var f=sre.Semantic.Type.NUMBER,g=e.match(/\W/)?sre.Semantic.Role.UNKNOWN:sre.Semantic.Role.PROTECTED;e=c.parseFromString("<"+f+' role="'+g+'">'+e+"</"+f+">","text/xml");b.push(e.documentElement)}return b};
+sre.MathspeakUtil.spaceoutIdentifier=function(a){var b=a.textContent;if(!b.match(/[a-zA-Z]+/))return a.setAttribute("role",sre.SemanticAttr.Role.PROTECTED),[a];a=b.split("");for(var b=[],c=new sre.SystemExternal.xmldom.DOMParser,d=0,e;e=a[d];d++){var f=sre.Semantic.Type.IDENTIFIER;e=c.parseFromString("<"+f+' role="'+sre.Semantic.Role.UNKNOWN+'">'+e+"</"+f+">","text/xml");b.push(e.documentElement)}return b};
+sre.MathspeakUtil.nestingBarriers=[sre.Semantic.Type.CASES,sre.Semantic.Type.CELL,sre.Semantic.Type.INTEGRAL,sre.Semantic.Type.LINE,sre.Semantic.Type.MATRIX,sre.Semantic.Type.MULTILINE,sre.Semantic.Type.OVERSCORE,sre.Semantic.Type.ROOT,sre.Semantic.Type.ROW,sre.Semantic.Type.SQRT,sre.Semantic.Type.SUBSCRIPT,sre.Semantic.Type.SUPERSCRIPT,sre.Semantic.Type.TABLE,sre.Semantic.Type.UNDERSCORE,sre.Semantic.Type.VECTOR];sre.MathspeakUtil.nestingDepth={};
+sre.MathspeakUtil.getNestingDepth=function(a,b,c,d,e,f){d=d||sre.MathspeakUtil.nestingBarriers;e=e||{};f=f||function(a){return!1};var g=(new sre.SystemExternal.xmldom.XMLSerializer).serializeToString(b);sre.MathspeakUtil.nestingDepth[a]||(sre.MathspeakUtil.nestingDepth[a]={});if(sre.MathspeakUtil.nestingDepth[a][g])return sre.MathspeakUtil.nestingDepth[a][g];if(f(b)||0>c.indexOf(b.tagName))return 0;b=sre.MathspeakUtil.computeNestingDepth_(b,c,sre.BaseUtil.setdifference(d,c),e,f,0);return sre.MathspeakUtil.nestingDepth[a][g]=
+b};sre.MathspeakUtil.containsAttr=function(a,b){if(!a.attributes)return!1;for(var c=sre.DomUtil.toArray(a.attributes),d=0,e;e=c[d];d++)if(b[e.nodeName]===e.nodeValue)return!0;return!1};
+sre.MathspeakUtil.computeNestingDepth_=function(a,b,c,d,e,f){if(e(a)||-1<c.indexOf(a.tagName)||sre.MathspeakUtil.containsAttr(a,d))return f;-1<b.indexOf(a.tagName)&&f++;if(!a.childNodes||0===a.childNodes.length)return f;a=sre.DomUtil.toArray(a.childNodes);return Math.max.apply(null,a.map(function(a){return sre.MathspeakUtil.computeNestingDepth_(a,b,c,d,e,f)}))};
+sre.MathspeakUtil.fractionNestingDepth=function(a){return sre.MathspeakUtil.getNestingDepth("fraction",a,["fraction"],sre.MathspeakUtil.nestingBarriers,{},function(a){return sre.MathspeakUtil.vulgarFractionSmall(a)})};sre.MathspeakUtil.openingFractionVerbose=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return Array(a+1).join("Start")+"Fraction"};sre.MathspeakUtil.closingFractionVerbose=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return Array(a+1).join("End")+"Fraction"};
+sre.MathspeakUtil.overFractionVerbose=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return Array(a+1).join("Over")};sre.MathspeakUtil.openingFractionBrief=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return Array(a+1).join("Start")+"Frac"};sre.MathspeakUtil.closingFractionBrief=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return Array(a+1).join("End")+"Frac"};sre.MathspeakUtil.nestingToString=function(a){switch(a){case 1:return"";case 2:return"Twice";default:return a.toString()}};
+sre.MathspeakUtil.openingFractionSbrief=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return 1===a?"Frac":"Nest"+sre.MathspeakUtil.nestingToString(a-1)+"Frac"};sre.MathspeakUtil.closingFractionSbrief=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return 1===a?"EndFrac":"Nest"+sre.MathspeakUtil.nestingToString(a-1)+"EndFrac"};
+sre.MathspeakUtil.overFractionSbrief=function(a){a=sre.MathspeakUtil.fractionNestingDepth(a);return 1===a?"Over":"Nest"+sre.MathspeakUtil.nestingToString(a-1)+"Over"};sre.MathspeakUtil.onesNumbers=" one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen".split(" ");sre.MathspeakUtil.tensNumbers="  twenty thirty forty fifty sixty seventy eighty ninety".split(" ");sre.MathspeakUtil.largeNumbers=" thousand million billion trillion quadrillion quintillion sextillion septillion octillion nonillion decillion".split(" ");
+sre.MathspeakUtil.hundredsToWords=function(a){a%=1E3;var b;b=""+(sre.MathspeakUtil.onesNumbers[Math.floor(a/100)]?sre.MathspeakUtil.onesNumbers[Math.floor(a/100)]+"-hundred":"");(a%=100)&&(b=b+(b?"-":"")+(sre.MathspeakUtil.onesNumbers[a]||sre.MathspeakUtil.tensNumbers[Math.floor(a/10)]+"-"+sre.MathspeakUtil.onesNumbers[a%10]));return b};
+sre.MathspeakUtil.numberToWords=function(a){if(a>=Math.pow(10,36))return a.toString();for(var b=0,c="";0<a;)a%1E3&&(c=sre.MathspeakUtil.hundredsToWords(a%1E3)+(b?"-"+sre.MathspeakUtil.largeNumbers[b]+"-":"")+c),a=Math.floor(a/1E3),b++;return c};
+sre.MathspeakUtil.numberToOrdinal=function(a,b){if(2===a)return b?"halves":"half";var c=sre.MathspeakUtil.numberToWords(a),c=c.match(/one$/)?c.slice(0,-3)+"first":c.match(/two$/)?c.slice(0,-3)+"second":c.match(/three$/)?c.slice(0,-5)+"third":c.match(/five$/)?c.slice(0,-4)+"fifth":c.match(/eight$/)?c.slice(0,-5)+"eighth":c.match(/nine$/)?c.slice(0,-4)+"ninth":c.match(/twelve$/)?c.slice(0,-5)+"twelfth":c.match(/ty$/)?c.slice(0,-2)+"tieth":c+"th";return b?c+"s":c};
+sre.MathspeakUtil.simpleOrdinal=function(a){var b=a%100,c=a.toString();if(10<b&&20>b)return c+"th";switch(a%10){case 1:return c+"st";case 2:return c+"nd";case 3:return c+"rd";default:return c+"th"}};sre.MathspeakUtil.ordinalCounter=function(a,b){var c=0;return function(){return sre.MathspeakUtil.simpleOrdinal(++c)+" "+b}};
+sre.MathspeakUtil.convertVulgarFraction_=function(a){if(!a.childNodes||!a.childNodes[0]||!a.childNodes[0].childNodes||2>a.childNodes[0].childNodes.length||a.childNodes[0].childNodes[0].tagName!==sre.SemanticAttr.Type.NUMBER||a.childNodes[0].childNodes[0].getAttribute("role")!==sre.SemanticAttr.Role.INTEGER||a.childNodes[0].childNodes[1].tagName!==sre.SemanticAttr.Type.NUMBER||a.childNodes[0].childNodes[1].getAttribute("role")!==sre.SemanticAttr.Role.INTEGER)return{convertible:!1,content:a.textContent};
+var b=a.childNodes[0].childNodes[1].textContent;a=a.childNodes[0].childNodes[0].textContent;var c=Number(b),d=Number(a);return isNaN(c)||isNaN(d)?{convertible:!1,content:a+" Over "+b}:{convertible:!0,enumerator:d,denominator:c}};sre.MathspeakUtil.vulgarFraction=function(a){a=sre.MathspeakUtil.convertVulgarFraction_(a);return a.convertible&&a.enumerator&&a.denominator?sre.MathspeakUtil.numberToWords(a.enumerator)+"-"+sre.MathspeakUtil.numberToOrdinal(a.denominator,1!==a.enumerator):a.content||""};
+sre.MathspeakUtil.vulgarFractionSmall=function(a){var b=sre.MathspeakUtil.convertVulgarFraction_(a);return b.convertible?(a=b.enumerator,b=b.denominator,0<a&&10>a&&0<b&&100>b):!1};sre.MathspeakUtil.isSmallVulgarFraction=function(a){return sre.MathspeakUtil.vulgarFractionSmall(a)?[a]:[]};
+sre.MathspeakUtil.nestedSubSuper=function(a,b,c){for(;a.parentNode;){var d=a.parentNode,e=d.parentNode,f=a.getAttribute&&a.getAttribute("role");if(e.tagName===sre.Semantic.Type.SUBSCRIPT&&a===d.childNodes[1]||e.tagName===sre.Semantic.Type.TENSOR&&f&&(f===sre.Semantic.Role.LEFTSUB||f===sre.Semantic.Role.RIGHTSUB))b=c.sub+" "+b;if(e.tagName===sre.Semantic.Type.SUPERSCRIPT&&a===d.childNodes[1]||e.tagName===sre.Semantic.Type.TENSOR&&f&&(f===sre.Semantic.Role.LEFTSUPER||f===sre.Semantic.Role.RIGHTSUPER))b=
+c.sup+" "+b;a=e}return b.trim()};sre.MathspeakUtil.subscriptVerbose=function(a){return sre.MathspeakUtil.nestedSubSuper(a,"Subscript",{sup:"Super",sub:"Sub"})};sre.MathspeakUtil.subscriptBrief=function(a){return sre.MathspeakUtil.nestedSubSuper(a,"Sub",{sup:"Sup",sub:"Sub"})};sre.MathspeakUtil.superscriptVerbose=function(a){return sre.MathspeakUtil.nestedSubSuper(a,"Superscript",{sup:"Super",sub:"Sub"})};
+sre.MathspeakUtil.superscriptBrief=function(a){return sre.MathspeakUtil.nestedSubSuper(a,"Sup",{sup:"Sup",sub:"Sub"})};sre.MathspeakUtil.baselineVerbose=function(a){return(a=sre.MathspeakUtil.nestedSubSuper(a,"",{sup:"Super",sub:"Sub"}))?a.replace(/Sub$/,"Subscript").replace(/Super$/,"Superscript"):"Baseline"};sre.MathspeakUtil.baselineBrief=function(a){return sre.MathspeakUtil.nestedSubSuper(a,"",{sup:"Sup",sub:"Sub"})||"Base"};
+sre.MathspeakUtil.radicalNestingDepth=function(a){return sre.MathspeakUtil.getNestingDepth("radical",a,["sqrt","root"],sre.MathspeakUtil.nestingBarriers,{})};sre.MathspeakUtil.nestedRadical=function(a,b,c){a=sre.MathspeakUtil.radicalNestingDepth(a);return 1===a?c:b+sre.MathspeakUtil.nestingToString(a-1)+c};sre.MathspeakUtil.openingRadicalVerbose=function(a){return sre.MathspeakUtil.nestedRadical(a,"Nested","StartRoot")};
+sre.MathspeakUtil.closingRadicalVerbose=function(a){return sre.MathspeakUtil.nestedRadical(a,"Nested","EndRoot")};sre.MathspeakUtil.indexRadicalVerbose=function(a){return sre.MathspeakUtil.nestedRadical(a,"Nested","RootIndex")};sre.MathspeakUtil.openingRadicalBrief=function(a){return sre.MathspeakUtil.nestedRadical(a,"Nest","StartRoot")};sre.MathspeakUtil.closingRadicalBrief=function(a){return sre.MathspeakUtil.nestedRadical(a,"Nest","EndRoot")};
+sre.MathspeakUtil.indexRadicalBrief=function(a){return sre.MathspeakUtil.nestedRadical(a,"Nest","RootIndex")};sre.MathspeakUtil.openingRadicalSbrief=function(a){return sre.MathspeakUtil.nestedRadical(a,"Nest","Root")};sre.MathspeakUtil.indexRadicalSbrief=function(a){return sre.MathspeakUtil.nestedRadical(a,"Nest","Index")};
+sre.MathspeakUtil.underscoreNestingDepth=function(a){return sre.MathspeakUtil.getNestingDepth("underscore",a,["underscore"],sre.MathspeakUtil.nestingBarriers,{},function(a){return a.tagName&&a.tagName===sre.Semantic.Type.UNDERSCORE&&a.childNodes[0].childNodes[1].getAttribute("role")===sre.Semantic.Role.UNDERACCENT})};sre.MathspeakUtil.nestedUnderscore=function(a){a=sre.MathspeakUtil.underscoreNestingDepth(a);return Array(a).join("Under")+"Underscript"};
+sre.MathspeakUtil.overscoreNestingDepth=function(a){return sre.MathspeakUtil.getNestingDepth("overscore",a,["overscore"],sre.MathspeakUtil.nestingBarriers,{},function(a){return a.tagName&&a.tagName===sre.Semantic.Type.OVERSCORE&&a.childNodes[0].childNodes[1].getAttribute("role")===sre.Semantic.Role.OVERACCENT})};sre.MathspeakUtil.nestedOverscore=function(a){a=sre.MathspeakUtil.overscoreNestingDepth(a);return Array(a).join("Over")+"Overscript"};
+sre.MathspeakUtil.determinantIsSimple=function(a){if(a.tagName!==sre.Semantic.Type.MATRIX||a.getAttribute("role")!==sre.Semantic.Role.DETERMINANT)return[];for(var b=sre.XpathUtil.evalXPath("children/row/children/cell/children/*",a),c=0,d;d=b[c];c++)if(d.tagName!==sre.Semantic.Type.NUMBER){if(d.tagName===sre.Semantic.Type.IDENTIFIER&&(d=d.getAttribute("role"),d===sre.Semantic.Role.LATINLETTER||d===sre.Semantic.Role.GREEKLETTER||d===sre.Semantic.Role.OTHERLETTER))continue;return[]}return[a]};
+sre.MathspeakUtil.determinantMarkSimple=function(a){sre.XpathUtil.evalXPath("children/row",a).forEach(function(a){a.setAttribute("sre_flag","simple")});return""};sre.MathspeakUtil.determinantUnMarkSimple=function(a){sre.XpathUtil.evalXPath("children/row",a).forEach(function(a){a.removeAttribute("sre_flag")});return""};
+sre.MathspeakUtil.generateBaselineConstraint=function(){for(var a=function(a){return a.map(function(a){return"ancestor::"+a})},b="not("+a(["subscript","superscript","tensor"]).join(" or ")+")",c=a(["relseq","multrel"]),a=a(["fraction","punctuation","fenced","sqrt","root"]),d=[],e=0,f;f=a[e];e++)d=d.concat(c.map(function(a){return f+"/"+a}));c="not("+d.join(" | ")+")";return["ancestor::*/following-sibling::*",b,c].join(" and ")};sre.StoreUtil={};sre.StoreUtil.nodeCounter=function(a,b){var c=a.length,d=0,e=b;b||(e="");return function(){d<c&&(d+=1);return e+" "+d}};sre.AbstractionRules=function(){sre.MathStore.call(this)};goog.inherits(sre.AbstractionRules,sre.MathStore);goog.addSingletonGetter(sre.AbstractionRules);sre.AbstractionRules.mathStore=sre.AbstractionRules.getInstance();sre.AbstractionRules.defineRule_=goog.bind(sre.AbstractionRules.mathStore.defineRule,sre.AbstractionRules.mathStore);sre.AbstractionRules.defineRuleAlias_=goog.bind(sre.AbstractionRules.mathStore.defineRulesAlias,sre.AbstractionRules.mathStore);
+sre.AbstractionRules.defineSpecialisedRule_=goog.bind(sre.AbstractionRules.mathStore.defineSpecialisedRule,sre.AbstractionRules.mathStore);sre.AbstractionRules.defineUniqueRuleAlias_=goog.bind(sre.AbstractionRules.mathStore.defineUniqueRuleAlias,sre.AbstractionRules.mathStore);
+sre.AbstractionRules.initAbstractionRules_=function(){(0,sre.AbstractionRules.defineRule_)("abstr-identifier","mathspeak.default",'[t] "collapsed long identifier"',"self::identifier[@alternative]","self::*","self::*","self::*","self::*","self::*");(0,sre.AbstractionRules.defineRule_)("abstr-identifier","mathspeak.brief",'[t] "collapsed identifier"',"self::identifier[@alternative]","self::*","self::*","self::*","self::*","self::*");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-identifier",
+"mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-number","mathspeak.default",'[t] "collapsed long number"',"self::number[@alternative]");(0,sre.AbstractionRules.defineRule_)("abstr-number","mathspeak.brief",'[t] "collapsed number"',"self::number[@alternative]");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-number","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-mixed-number","mathspeak.default",'[t] "collapsed long mixed number"',
+"self::number[@alternative]",'@role="mixed"');(0,sre.AbstractionRules.defineRule_)("abstr-mixed-number","mathspeak.brief",'[t] "collapsed mixed number"',"self::number[@alternative]",'@role="mixed"');(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-mixed-number","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-text","mathspeak.default",'[t] "collapsed text"',"self::text[@alternative]");(0,sre.AbstractionRules.defineRule_)("abstr-function","mathspeak.default",
+'[t] "collapsed functional expression"',"self::function[@alternative]","self::*","self::*");(0,sre.AbstractionRules.defineRule_)("abstr-function","mathspeak.brief",'[t] "collapsed function"',"self::function[@alternative]","self::*","self::*");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-function","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-lim","mathspeak.default",'[t] "collapsed limit function"',"self::function[@alternative]",'@role="limit function"');
+(0,sre.AbstractionRules.defineRule_)("abstr-lim","mathspeak.brief",'[t] "collapsed lim"',"self::function[@alternative]",'@role="limit function"');(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-lim","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-fraction","mathspeak.default",'[t] "collapsed fraction"',"self::fraction[@alternative]");(0,sre.AbstractionRules.defineRule_)("abstr-fraction","mathspeak.brief",'[t] "collapsed frac"',"self::fraction[@alternative]");
+(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-fraction","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-continued-fraction","mathspeak.default",'[t] "collapsed continued fraction"',"self::fraction[@alternative]",'children/*[2]/descendant-or-self::*[@role="ellipsis"]',"self::*","self::*");(0,sre.AbstractionRules.defineRule_)("abstr-continued-fraction","mathspeak.brief",'[t] "collapsed continued frac"',"self::fraction[@alternative]",'children/*[2]/descendant-or-self::*[@role="ellipsis"]',
+"self::*","self::*");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-continued-fraction","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-sqrt","mathspeak.default",'[t] "collapsed square root"',"self::sqrt[@alternative]");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-sqrt","mathspeak.default","mathspeak.brief");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-sqrt","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-sqrt-nested",
+"mathspeak.default",'[t] "collapsed nested square root"',"self::sqrt[@alternative]","children/*/descendant::sqrt or children/*/descendant::root");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-sqrt-nested","mathspeak.default","mathspeak.brief");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-sqrt-nested","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-root","mathspeak.default",'[t] "collapsed root of index"; [n] children/*[1]; [t] "endindex"',"self::root[@alternative]",
+"following-sibling::* or ancestor::*/following-sibling::*");(0,sre.AbstractionRules.defineRule_)("abstr-root","mathspeak.brief",'[t] "collapsed root"',"self::root[@alternative]");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-root","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-root","mathspeak.default",'[t] "collapsed nested root of index"; [n] children/*[1]',"self::root[@alternative]","children/*/descendant::sqrt or children/*/descendant::root");(0,sre.AbstractionRules.defineRule_)("abstr-root",
+"mathspeak.default",'[t] "collapsed nested root of index"; [n] children/*[1]; [t] "endindex"',"self::root[@alternative]","children/*/descendant::sqrt or children/*/descendant::root","following-sibling::* or ancestor::*/following-sibling::*");(0,sre.AbstractionRules.defineRule_)("abstr-root","mathspeak.brief",'[t] "collapsed nested root"',"self::root[@alternative]","children/*/descendant::sqrt or children/*/descendant::root");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-root","mathspeak.brief",
+"mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-superscript","mathspeak.default",'[t] "collapsed power"',"self::superscript[@alternative]","self::*","self::*","self::*","self::*");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-superscript","mathspeak.default","mathspeak.brief");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-superscript","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-subscript","mathspeak.default",'[t] "collapsed subscript"',
+"self::subscript[@alternative]","self::*","self::*","self::*","self::*");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-subscript","mathspeak.default","mathspeak.brief");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-subscript","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-subsup","mathspeak.default",'[t] "collapsed power with subscript"',"self::superscript[@alternative]",'name(children/*[1])="subscript"',"self::*","self::*","self::*","self::*");
+(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-subsup","mathspeak.default","mathspeak.brief");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-subsup","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-infixop","mathspeak.default",'[t] "collapsed"; [t] @role; [t] "with"; [t] count(./children/*); [t] "elements"',"self::infixop[@alternative]","self::*");(0,sre.AbstractionRules.defineRule_)("abstr-infixop","mathspeak.default",'[t] "collapsed"; [t] @role; [t] "with variable number of elements"',
+"self::infixop[@alternative]","count(./children/*)>2",'./children/punctuation[@role="ellipsis"]',"self::*");(0,sre.AbstractionRules.defineRule_)("abstr-infixop","mathspeak.brief",'[t] "collapsed"; [t] @role',"self::infixop[@alternative]","self::*");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-infixop","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-addition","mathspeak.default",'[t] "collapsed sum with"; [t] count(./children/*); [t] "summands"',"self::infixop[@alternative]",
+'@role="addition"');(0,sre.AbstractionRules.defineRule_)("abstr-addition","mathspeak.brief",'[t] "collapsed sum"',"self::infixop[@alternative]",'@role="addition"');(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-addition","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-var-addition","mathspeak.default",'[t] "collapsed sum with variable number of summands"',"self::infixop[@alternative]",'@role="addition"',"count(./children/*)>2",'./children/punctuation[@role="ellipsis"]');
+(0,sre.AbstractionRules.defineRule_)("abstr-multiplication","mathspeak.default",'[t] "collapsed product with"; [t] count(./children/*); [t] "factors"',"self::infixop[@alternative]",'@role="multiplication"');(0,sre.AbstractionRules.defineRule_)("abstr-multiplication","mathspeak.brief",'[t] "collapsed product"',"self::infixop[@alternative]",'@role="multiplication"');(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-multiplication","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRuleAlias_)("abstr-multiplication",
+"self::infixop[@alternative]",'@role="implicit"');(0,sre.AbstractionRules.defineRule_)("abstr-var-multiplication","mathspeak.default",'[t] "collapsed product with variable number of factors"',"self::infixop[@alternative]",'@role="multiplication"',"count(./children/*)>2",'./children/punctuation[@role="ellipsis"]');(0,sre.AbstractionRules.defineRuleAlias_)("abstr-var-multiplication","self::infixop[@alternative]",'@role="implicit"',"count(./children/*)>2",'./children/punctuation[@role="ellipsis"]');
+(0,sre.AbstractionRules.defineRule_)("abstr-vector","mathspeak.default",'[t] "collapsed"; [t] count(./children/*) ; [t] "dimensional vector"',"self::vector[@alternative]");(0,sre.AbstractionRules.defineRule_)("abstr-vector","mathspeak.brief",'[t] "collapsed vector"',"self::vector[@alternative]");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-vector","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-var-vector","mathspeak.default",'[t] "collapsed n dimensional vector"',
+"self::vector[@alternative]",'./children/*/children/punctuation[@role="ellipsis"]');(0,sre.AbstractionRules.defineRule_)("abstr-binomial","mathspeak.default",'[t] "collapsed binomial"',"self::vector[@alternative]",'@role="binomial"');(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-binomial","mathspeak.default","mathspeak.brief");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-binomial","mathspeak.default","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-determinant","mathspeak.default",
+'[t] "collapsed" ; [t] count(./children/*); [t] "dimensional determinant"',"self::matrix[@alternative]",'@role="determinant"',"self::*");(0,sre.AbstractionRules.defineRule_)("abstr-determinant","mathspeak.brief",'[t] "collapsed determinant"',"self::matrix[@alternative]",'@role="determinant"',"self::*");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-determinant","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-var-determinant","mathspeak.default",'[t] "collapsed n dimensional determinant"',
+"self::matrix[@alternative]",'@role="determinant"','./children/*/children/*/children/punctuation[@role="ellipsis"]');(0,sre.AbstractionRules.defineRule_)("abstr-squarematrix","mathspeak.default",'[t] "collapsed" ; [t] count(./children/*); [t] "dimensional square matrix"',"self::matrix[@alternative]",'@role="squarematrix"');(0,sre.AbstractionRules.defineRule_)("abstr-squarematrix","mathspeak.brief",'[t] "collapsed square matrix"',"self::matrix[@alternative]",'@role="squarematrix"');(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-squarematrix",
+"mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-rowvector","mathspeak.default",'[t] "collapsed" ; [t] count(./children/row/children/*); [t] "dimensional row vector"',"self::matrix[@alternative]",'@role="rowvector"');(0,sre.AbstractionRules.defineRule_)("abstr-rowvector","mathspeak.brief",'[t] "collapsed row vector"',"self::matrix[@alternative]",'@role="rowvector"');(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-rowvector","mathspeak.brief","mathspeak.sbrief");
+(0,sre.AbstractionRules.defineRule_)("abstr-var-matrix","mathspeak.default",'[t] "collapsed n dimensional row vector"',"self::matrix[@alternative]",'@role="rowvector"','./children/*/children/*/children/punctuation[@role="ellipsis"]');(0,sre.AbstractionRules.defineRule_)("abstr-matrix","mathspeak.default",'[t] "collapsed"; [t] count(children/*);  [t] "by";[t] count(children/*[1]/children/*); [t] "matrix"',"self::matrix[@alternative]");(0,sre.AbstractionRules.defineRule_)("abstr-matrix","mathspeak.brief",
+'[t] "collapsed matrix"',"self::matrix[@alternative]");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-matrix","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-var-matrix","mathspeak.default",'[t] "collapsed n by m dimensional matrix"',"self::matrix[@alternative]",'./children/*/children/*/children/punctuation[@role="ellipsis"]');(0,sre.AbstractionRules.defineRule_)("abstr-cases","mathspeak.default",'[t] "collapsed case statement";[t] "with"; [t] count(children/*); [t] "cases"',
+"self::cases[@alternative]");(0,sre.AbstractionRules.defineRule_)("abstr-cases","mathspeak.brief",'[t] "collapsed case statement"',"self::cases[@alternative]");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-cases","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-var-cases","mathspeak.default",'[t] "collapsed case statement with variable number of cases"',"self::cases[@alternative]",'./children/row/children/cell/children/punctuation[@role="ellipsis"]or ./children/line/children/punctuation[@role="ellipsis"]');
+(0,sre.AbstractionRules.defineRule_)("abstr-punctuated","mathspeak.default",'[t] "collapsed"; [n] content/*[1]; [t] "separated list";[t] "of length"; [t] count(children/*) - count(content/*)',"self::punctuated[@alternative]");(0,sre.AbstractionRules.defineRule_)("abstr-punctuated","mathspeak.brief",'[t] "collapsed"; [n] content/*[1]; [t] "separated list"',"self::punctuated[@alternative]");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-punctuated","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-var-punctuated",
+"mathspeak.default",'[t] "collapsed"; [n] content/*[1]; [t] "separated list";[t] "of variable length"',"self::punctuated[@alternative]",'./children/punctuation[@role="ellipsis"]');(0,sre.AbstractionRules.defineRule_)("abstr-bigop","mathspeak.default",'[t] "collapsed"; [n] content/*[1]',"self::bigop[@alternative]","self::*");(0,sre.AbstractionRules.defineRule_)("abstr-integral","mathspeak.default",'[t] "collapsed integral"',"self::*[@alternative]",'@role="integral"',"self::*");(0,sre.AbstractionRules.defineRule_)("abstr-relation",
+"mathspeak.default",'[t] "collapsed"; [n] @role;',"self::relseq[@alternative]","count(./children/*)=2");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-relation","mathspeak.default","mathspeak.brief");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-relation","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-relation","mathspeak.default",'[t] "collapsed"; [n] @role; [t] "sequence"; [t] "with"; [t] count(./children/*); [t] "elements"',"self::relseq[@alternative]",
+"count(./children/*)>2");(0,sre.AbstractionRules.defineRule_)("abstr-relation","mathspeak.brief",'[t] "collapsed"; [n] @role; [t] "sequence"',"self::relseq[@alternative]","count(./children/*)>2");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-relation","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-var-relation","mathspeak.default",'[t] "collapsed"; [n] @role; [t] "sequence"; [t] "with variable number of elements"',"self::relseq[@alternative]","count(./children/*)>2",
+'./children/punctuation[@role="ellipsis"]');(0,sre.AbstractionRules.defineUniqueRuleAlias_)("abstr-relation","mathspeak.default","self::multirel[@alternative]",'@role!="unknown"',"count(./children/*)>2");(0,sre.AbstractionRules.defineUniqueRuleAlias_)("abstr-relation","mathspeak.brief","self::multirel[@alternative]",'@role!="unknown"',"count(./children/*)>2");(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-relation","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRuleAlias_)("abstr-var-relation",
+"self::multirel[@alternative]",'@role!="unknown"',"count(./children/*)>2",'./children/punctuation[@role="ellipsis"]');(0,sre.AbstractionRules.defineRule_)("abstr-multirel","mathspeak.default",'[t] "collapsed relation sequence"; [t] "with"; [t] count(./children/*); [t] "elements"',"self::multirel[@alternative]","count(./children/*)>2");(0,sre.AbstractionRules.defineRule_)("abstr-multirel","mathspeak.brief",'[t] "collapsed relation sequence"',"self::multirel[@alternative]","count(./children/*)>2");
+(0,sre.AbstractionRules.defineSpecialisedRule_)("abstr-multirel","mathspeak.brief","mathspeak.sbrief");(0,sre.AbstractionRules.defineRule_)("abstr-var-multirel","mathspeak.default",'[t] "collapsed relation sequence with variable number of elements"',"self::multirel[@alternative]","count(./children/*)>2",'./children/punctuation[@role="ellipsis"]')};sre.AbstractionRules.getInstance().initializer=[sre.AbstractionRules.initAbstractionRules_];sre.ClearspeakRules=function(){sre.MathStore.call(this)};goog.inherits(sre.ClearspeakRules,sre.MathStore);goog.addSingletonGetter(sre.ClearspeakRules);sre.ClearspeakRules.mathStore=sre.ClearspeakRules.getInstance();sre.ClearspeakRules.defineRule_=goog.bind(sre.ClearspeakRules.mathStore.defineRule,sre.ClearspeakRules.mathStore);
+sre.ClearspeakRules.initClearspeakRules_=function(){(0,sre.ClearspeakRules.defineRule_)("fraction","mathspeak.clearspeak",'[t] "the fraction with numerator"; [n] children/*[1]; [p] (pause:300); [t] "and denominator"; [n] children/*[2]; [p] (pause:500)',"self::fraction");(0,sre.ClearspeakRules.defineRule_)("sqrt","mathspeak.clearspeak",'[t] "the square root of"; [n] children/*[1]; [p] (pause:500)',"self::sqrt")};sre.ClearspeakRules.getInstance().initializer=[sre.ClearspeakRules.initClearspeakRules_];sre.MathmlStore=function(){sre.MathStore.call(this)};goog.inherits(sre.MathmlStore,sre.MathStore);goog.addSingletonGetter(sre.MathmlStore);sre.MathmlStore.prototype.defineMathmlRule=function(a,b,c){this.defineRule(a,b,c,"self::mathml:"+a)};sre.MathmlStore.prototype.defineDefaultMathmlRule=function(a,b){this.defineRule(a,"default.default",b,"self::mathml:"+a)};sre.MathmlStoreUtil={};sre.MathmlStoreUtil.matchMathjaxToMathml=function(a){return sre.Engine.getInstance().alternativeHost.querySelector("#"+a.id)};sre.MathmlStoreUtil.retrieveMathjaxExtender=function(a){return(a=sre.MathmlStoreUtil.matchMathjaxToMathml(a))?[a]:[]};sre.MathmlStoreUtil.retrieveMathjaxLeaf=function(a){return(a=sre.MathmlStoreUtil.matchMathjaxToMathml(a))?[a]:[]};
+sre.MathmlStoreUtil.checkMathjaxTag=function(a,b){var c=sre.MathmlStoreUtil.matchMathjaxToMathml(a);return c&&c.tagName.toUpperCase()==b?[c]:[]};sre.MathmlStoreUtil.checkMathjaxMunder=function(a){return sre.MathmlStoreUtil.checkMathjaxTag(a,"MUNDER")};sre.MathmlStoreUtil.checkMathjaxMover=function(a){return sre.MathmlStoreUtil.checkMathjaxTag(a,"MOVER")};sre.MathmlStoreUtil.checkMathjaxMsub=function(a){return sre.MathmlStoreUtil.checkMathjaxTag(a,"MSUB")};
+sre.MathmlStoreUtil.checkMathjaxMsup=function(a){return sre.MathmlStoreUtil.checkMathjaxTag(a,"MSUP")};sre.MathmlStoreUtil.mfencedSeparators=function(a,b){var c=sre.MathUtil.nextSeparatorFunction(b);return function(){return c?[new sre.AuditoryDescription({text:c(),preprocess:!0})]:[]}};
+sre.MathmlStoreUtil.contentIterator=function(a,b){var c=0<a.length?sre.XpathUtil.evalXPath("../../content/*",a[0]):[];return function(){var a=c.shift(),e=b?[new sre.AuditoryDescription({text:b,preprocess:!0})]:[];if(!a)return e;a=sre.SpeechRuleEngine.getInstance().evaluateNode(a);return e.concat(a)}};
+sre.MathmlStoreUtil.hideFont=function(a){if(a.hasAttribute("font")){var b=a.getAttribute("font");a.removeAttribute("font");sre.SpeechRuleEngine.getInstance().setGlobalParameter("remove",b);a.setAttribute("hiddenfont",b)}return[a]};sre.MathmlStoreUtil.showFont=function(a){if(a.hasAttribute("hiddenfont")){var b=a.getAttribute("hiddenfont");a.removeAttribute("hiddenfont");sre.SpeechRuleEngine.getInstance().setGlobalParameter("remove","");a.setAttribute("font",b)}return""};sre.MathmlStoreRules=function(){sre.MathmlStore.call(this)};goog.inherits(sre.MathmlStoreRules,sre.MathmlStore);goog.addSingletonGetter(sre.MathmlStoreRules);sre.MathmlStoreRules.mathStore=sre.MathmlStoreRules.getInstance();sre.MathmlStoreRules.defineDefaultMathmlRule_=goog.bind(sre.MathmlStoreRules.mathStore.defineDefaultMathmlRule,sre.MathmlStoreRules.mathStore);sre.MathmlStoreRules.defineRule_=goog.bind(sre.MathmlStoreRules.mathStore.defineRule,sre.MathmlStoreRules.mathStore);
+sre.MathmlStoreRules.defineRuleAlias_=goog.bind(sre.MathmlStoreRules.mathStore.defineRuleAlias,sre.MathmlStoreRules.mathStore);sre.MathmlStoreRules.addContextFunction_=goog.bind(sre.MathmlStoreRules.mathStore.contextFunctions.add,sre.MathmlStoreRules.mathStore.contextFunctions);sre.MathmlStoreRules.addCustomQuery_=goog.bind(sre.MathmlStoreRules.mathStore.customQueries.add,sre.MathmlStoreRules.mathStore.customQueries);
+sre.MathmlStoreRules.initCustomFunctions_=function(){(0,sre.MathmlStoreRules.addContextFunction_)("CTXFnodeCounter",sre.StoreUtil.nodeCounter);(0,sre.MathmlStoreRules.addContextFunction_)("CTXFmfSeparators",sre.MathmlStoreUtil.mfencedSeparators);(0,sre.MathmlStoreRules.addCustomQuery_)("CQFextender",sre.MathmlStoreUtil.retrieveMathjaxExtender);(0,sre.MathmlStoreRules.addCustomQuery_)("CQFmathmlmunder",sre.MathmlStoreUtil.checkMathjaxMunder);(0,sre.MathmlStoreRules.addCustomQuery_)("CQFmathmlmover",
+sre.MathmlStoreUtil.checkMathjaxMover);(0,sre.MathmlStoreRules.addCustomQuery_)("CQFmathmlmsub",sre.MathmlStoreUtil.checkMathjaxMsub);(0,sre.MathmlStoreRules.addCustomQuery_)("CQFmathmlmsup",sre.MathmlStoreUtil.checkMathjaxMsup);(0,sre.MathmlStoreRules.addCustomQuery_)("CQFlookupleaf",sre.MathmlStoreUtil.retrieveMathjaxLeaf)};
+sre.MathmlStoreRules.initDefaultRules_=function(){(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("math","[m] ./*");(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("semantics","[n] ./*[1]");(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mspace","[p] (pause:250)");(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mstyle","[m] ./*");(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mpadded","[m] ./*");(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("merror","[m] ./*");(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mphantom",
+"[m] ./*");(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mtext","[t] text(); [p] (pause:200)");(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mi","[n] text()");(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mo","[n] text() (rate:-0.1)");(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mn","[n] text()");(0,sre.MathmlStoreRules.defineRule_)("mtext-variant","default.default",'[t] "begin"; [t] @mathvariant (pause:150);[t] text() (pause:150); [t] "end"; [t] @mathvariant (pause:200)',"self::mathml:mtext",
+"@mathvariant",'@mathvariant!="normal"');(0,sre.MathmlStoreRules.defineRule_)("mi-variant","default.default","[t] @mathvariant; [n] text()","self::mathml:mi","@mathvariant",'@mathvariant!="normal"');(0,sre.MathmlStoreRules.defineRuleAlias_)("mi-variant","self::mathml:mn","@mathvariant",'@mathvariant!="normal"');(0,sre.MathmlStoreRules.defineRule_)("mo-variant","default.default","[t] @mathvariant; [n] text() (rate:-0.1)","self::mathml:mo","@mathvariant",'@mathvariant!="normal"');(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("ms",
+'[t] "string" (pitch:0.5, rate:0.5); [t] text()');(0,sre.MathmlStoreRules.defineRule_)("unit","default.default","[t] text() (annotation:unit, preprocess)","self::mathml:mi",'@class="MathML-Unit"');(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("msup",'[n] ./*[1]; [t] "super";[n] ./*[2] (pitch:0.35); [p] (pause:300)');(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("msubsup",'[n] ./*[1]; [t] "sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:200);[t] "super"; [n] ./*[3] (pitch:0.35); [p] (pause:300)');
+(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("msub",'[n] ./*[1]; [t] "sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:300)');(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mover",'[n] ./*[2] (pitch:0.35); [p] (pause:200); [t] "over"; [n] ./*[1]; [p] (pause:400)');(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("munder",'[n] ./*[2] (pitch:-0.35); [t] "under"; [n] ./*[1]; [p] (pause:400)');(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("munderover",'[n] ./*[2] (pitch:-0.35); [t] "under and"; [n] ./*[3] (pitch:0.35); [t] "over"; [n] ./*[1]; [p] (pause:400)');
+(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mrow","[m] ./*");(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("msqrt",'[t] "Square root of"; [m] ./* (rate:0.2); [p] (pause:400)');(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mroot",'[t] "root of order"; [n] ./*[2]; [t] "of";[n] ./*[1] (rate:0.2); [p] (pause:400)');(0,sre.MathmlStoreRules.defineDefaultMathmlRule_)("mfrac",' [p] (pause:400); [n] ./*[1] (pitch:0.3); [t] "divided by"; [n] ./*[2] (pitch:-0.3); [p] (pause:400)');(0,sre.MathmlStoreRules.defineRule_)("mfrac",
+"default.short",'[p] (pause:200); [t] "start frac";[n] ./*[1] (pitch:0.3); [t] "over"; [n] ./*[2] (pitch:-0.3); [p] (pause:400); [t] "end frac"',"self::mathml:mfrac");(0,sre.MathmlStoreRules.defineRule_)("mfenced-single","default.default",'[t] concat(substring(@open, 0 div boolean(@open)), substring("(", 0 div not(boolean(@open)))) (context:"opening"); [m] ./* (separator:@separators); [t] concat(substring(@close, 0 div boolean(@close)), substring(")", 0 div not(boolean(@close)))) (context:"closing")',
+"self::mathml:mfenced","string-length(string(@separators))=1");(0,sre.MathmlStoreRules.defineRule_)("mfenced-omit","default.default",'[t] concat(substring(@open, 0 div boolean(@open)), substring("(", 0 div not(boolean(@open)))) (context:"opening"); [m] ./*; [t] concat(substring(@close, 0 div boolean(@close)), substring(")", 0 div not(boolean(@close)))) (context:"closing")',"self::mathml:mfenced","@separators","string-length(string(@separators))=0",'string(@separators)=""');(0,sre.MathmlStoreRules.defineRule_)("mfenced-empty",
+"default.default",'[t] concat(substring(@open, 0 div boolean(@open)), substring("(", 0 div not(boolean(@open)))) (context:"opening"); [m] ./*;[t] concat(substring(@close, 0 div boolean(@close)), substring(")", 0 div not(boolean(@close)))) (context:"closing")',"self::mathml:mfenced","string-length(string(@separators))=1",'string(@separators)=" "');(0,sre.MathmlStoreRules.defineRule_)("mfenced-comma","default.default",'[t] concat(substring(@open, 0 div boolean(@open)), substring("(", 0 div not(boolean(@open)))) (context:"opening"); [m] ./* (separator:"comma");[t] concat(substring(@close, 0 div boolean(@close)), substring(")", 0 div not(boolean(@close)))) (context:"closing")',
+"self::mathml:mfenced");(0,sre.MathmlStoreRules.defineRule_)("mfenced-multi","default.default",'[t] concat(substring(@open, 0 div boolean(@open)), substring("(", 0 div not(boolean(@open)))) (context:"opening"); [m] ./* (sepFunc:CTXFmfSeparators, separator:@separators); [t] concat(substring(@close, 0 div boolean(@close)), substring(")", 0 div not(boolean(@close)))) (context:"closing")',"self::mathml:mfenced","string-length(string(@separators))>1");(0,sre.MathmlStoreRules.defineRule_)("mtable","default.default",
+'[t] "matrix"; [m] ./* (ctxtFunc:CTXFnodeCounter,context:"row",pause:100)',"self::mathml:mtable");(0,sre.MathmlStoreRules.defineRule_)("mtr","default.default",'[m] ./* (ctxtFunc:CTXFnodeCounter,context:"column",pause:100)',"self::mathml:mtr");(0,sre.MathmlStoreRules.defineRule_)("mtd","default.default","[m] ./*","self::mathml:mtd");(0,sre.MathmlStoreRules.defineRule_)("mtable","default.superbrief",'[t] count(child::mathml:mtr);  [t] "by";[t] count(child::mathml:mtr[1]/mathml:mtd); [t] "matrix";',
+"self::mathml:mtable");(0,sre.MathmlStoreRules.defineRule_)("mtable","default.short",'[t] "matrix"; [m] ./*',"self::mathml:mtable");(0,sre.MathmlStoreRules.defineRule_)("mtr","default.short","[m] ./*","self::mathml:mtr");(0,sre.MathmlStoreRules.defineRule_)("mtd","default.short",'[t] "Element"; [t] count(./preceding-sibling::mathml:mtd)+1;[t] count(./parent::mathml:mtr/preceding-sibling::mathml:mtr)+1;[p] (pause:500); [m] ./*',"self::mathml:mtd");(0,sre.MathmlStoreRules.defineRule_)("mmultiscripts-4",
+"default.default",'[n] ./*[1]; [p] (pause:200);[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:200);[t] "right sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:200);[t] "right super"; [n] ./*[3] (pitch:0.35); [p] (pause:300);',"self::mathml:mmultiscripts");(0,sre.MathmlStoreRules.defineRule_)("mmultiscripts-3-1","default.default",'[n] ./*[1]; [p] (pause:200);[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:200);[t] "right super"; [n] ./*[3] (pitch:0.35); [p] (pause:300);',
+"self::mathml:mmultiscripts","./mathml:none=./*[2]","./mathml:mprescripts=./*[4]");(0,sre.MathmlStoreRules.defineRule_)("mmultiscripts-3-2","default.default",'[n] ./*[1]; [p] (pause:200);[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:200);[t] "right sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:200);',"self::mathml:mmultiscripts","./mathml:none=./*[3]","./mathml:mprescripts=./*[4]");(0,sre.MathmlStoreRules.defineRule_)("mmultiscripts-3-3",
+"default.default",'[n] ./*[1]; [p] (pause:200);[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:200);[t] "right sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:200);[t] "right super"; [n] ./*[3] (pitch:0.35); [p] (pause:300);',"self::mathml:mmultiscripts","./mathml:none=./*[5]","./mathml:mprescripts=./*[4]");(0,sre.MathmlStoreRules.defineRule_)("mmultiscripts-3-4","default.default",'[n] ./*[1]; [p] (pause:200);[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);[t] "right sub"; [n] ./*[2] (pitch:-0.35); [p] (pause:200);[t] "right super"; [n] ./*[3] (pitch:0.35); [p] (pause:300);',
+"self::mathml:mmultiscripts","./mathml:none=./*[6]","./mathml:mprescripts=./*[4]");(0,sre.MathmlStoreRules.defineRule_)("mmultiscripts-2-1","default.default",'[n] ./*[1]; [p] (pause:200);[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:300);',"self::mathml:mmultiscripts","./mathml:none=./*[2]","./mathml:none=./*[3]","./mathml:mprescripts=./*[4]");(0,sre.MathmlStoreRules.defineRule_)("mmultiscripts-1-1","default.default",'[n] ./*[1]; [p] (pause:200);[t] "left super"; [n] ./*[6] (pitch:0.35); [p] (pause:300);',
+"self::mathml:mmultiscripts","./mathml:none=./*[2]","./mathml:none=./*[3]","./mathml:mprescripts=./*[4]","./mathml:none=./*[5]");(0,sre.MathmlStoreRules.defineRule_)("mmultiscripts-1-2","default.default",'[n] ./*[1]; [p] (pause:200);[t] "left sub"; [n] ./*[5] (pitch:-0.35); [p] (pause:200);',"self::mathml:mmultiscripts","./mathml:none=./*[2]","./mathml:none=./*[3]","./mathml:mprescripts=./*[4]","./mathml:none=./*[6]")};
+sre.MathmlStoreRules.initMathjaxRules_=function(){(0,sre.MathmlStoreRules.defineRule_)("mj-math","default.default","[n] ./*[1]/*[1]/*[1]",'self::span[@class="math"]');(0,sre.MathmlStoreRules.defineRule_)("mj-leaf","default.default","[n] CQFlookupleaf",'self::span[@class="mi"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-leaf",'self::span[@class="mo"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-leaf",'self::span[@class="mn"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-leaf",'self::span[@class="mtext"]');
+(0,sre.MathmlStoreRules.defineRule_)("mj-mo-ext","default.default","[n] CQFextender",'self::span[@class="mo"]',"./*[1]/*[1]/text()","./*[1]/*[2]/text()");(0,sre.MathmlStoreRules.defineRule_)("mj-texatom","default.default","[n] ./*[1]",'self::span[@class="texatom"]');(0,sre.MathmlStoreRules.defineRule_)("mj-msubsup","default.default",'[n] ./*[1]/*[1]/*[1]; [t] "sub"; [n] ./*[1]/*[3]/*[1] (pitch:-0.35);[p] (pause:200); [t] "super"; [n] ./*[1]/*[2]/*[1] (pitch:0.35);[p] (pause:300)','self::span[@class="msubsup"]');
+(0,sre.MathmlStoreRules.defineRule_)("mj-msub","default.default",'[n] ./*[1]/*[1]/*[1]; [t] "sub";[n] ./*[1]/*[2]/*[1] (pitch:-0.35); [p] (pause:300)','self::span[@class="msub"]');(0,sre.MathmlStoreRules.defineRule_)("mj-msup","default.default",'[n] ./*[1]/*[1]/*[1]; [t] "super";[n] ./*[1]/*[2]/*[1] (pitch:0.35); [p] (pause:300)','self::span[@class="msup"]');(0,sre.MathmlStoreRules.defineRule_)("mj-munderover","default.default",'[n] ./*[1]/*[2]/*[1] (pitch:0.35); [t] "under and";[n] ./*[1]/*[3]/*[1] (pitch:-0.35); [t] "over";[n] ./*[1]/*[1]/*[1]; [p] (pause:400)',
+'self::span[@class="munderover"]');(0,sre.MathmlStoreRules.defineRule_)("mj-munder","default.default",'[n] ./*[1]/*[2]/*[1] (pitch:0.35); [t] "under";[n] ./*[1]/*[1]/*[1]; [p] (pause:400)','self::span[@class="munder"]');(0,sre.MathmlStoreRules.defineRule_)("mj-mover","default.default",'[n] ./*[1]/*[2]/*[1] (pitch:0.35); [t] "over";[n] ./*[1]/*[1]/*[1]; [p] (pause:400)','self::span[@class="mover"]');(0,sre.MathmlStoreRules.defineRule_)("mj-mfrac","default.default",'[p] (pause:250); [n] ./*[1]/*[1]/*[1] (pitch:0.3); [p] (pause:250); [t] "divided by"; [n] ./*[1]/*[2]/*[1] (pitch:-0.3);[p] (pause:400)',
+'self::span[@class="mfrac"]');(0,sre.MathmlStoreRules.defineRule_)("mj-msqrt","default.default",'[t] "Square root of";[n] ./*[1]/*[1]/*[1] (rate:0.2); [p] (pause:400)','self::span[@class="msqrt"]');(0,sre.MathmlStoreRules.defineRule_)("mj-mroot","default.default",'[t] "root of order"; [n] ./*[1]/*[4]/*[1]; [t] "of";[n] ./*[1]/*[1]/*[1] (rate:0.2); [p] (pause:400)','self::span[@class="mroot"]');(0,sre.MathmlStoreRules.defineRule_)("mj-mfenced","default.default",'[t] "opening"; [n] ./*[1]; [m] ./*[position()>1 and position()<last()]; [t] "closing"; [n] ./*[last()]',
+'self::span[@class="mfenced"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-leaf",'self::span[@class="mtable"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-leaf",'self::span[@class="mmultiscripts"]')};
+sre.MathmlStoreRules.initAliases_=function(){(0,sre.MathmlStoreRules.defineRuleAlias_)("mspace",'self::span[@class="mspace"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("mstyle",'self::span[@class="mstyle"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("mpadded",'self::span[@class="mpadded"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("merror",'self::span[@class="merror"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("mphantom",'self::span[@class="mphantom"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("ms",
+'self::span[@class="ms"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("mrow",'self::span[@class="mrow"]');(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-msub",'self::span[@class="msubsup"]',"CQFmathmlmsub");(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-msup",'self::span[@class="msubsup"]',"CQFmathmlmsup");(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-munder",'self::span[@class="munderover"]',"CQFmathmlmunder");(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-mover",'self::span[@class="munderover"]',"CQFmathmlmover")};
+sre.MathmlStoreRules.initSpecializationRules_=function(){(0,sre.MathmlStoreRules.defineRule_)("square","default.default",'[n] ./*[1]; [t] "square" (pitch:0.35); [p] (pause:300)',"self::mathml:msup","./*[2][text()=2]");(0,sre.MathmlStoreRules.defineRuleAlias_)("square","self::mathml:msup","./mathml:mrow=./*[2]","count(./*[2]/*)=1","./*[2]/*[1][text()=2]");(0,sre.MathmlStoreRules.defineRule_)("cube","default.default",'[n] ./*[1]; [t] "cube" (pitch:0.35); [p] (pause:300)',"self::mathml:msup","./*[2][text()=3]");
+(0,sre.MathmlStoreRules.defineRuleAlias_)("cube","self::mathml:msup","./mathml:mrow=./*[2]","count(./*[2]/*)=1","./*[2]/*[1][text()=3]");(0,sre.MathmlStoreRules.defineRule_)("square-sub","default.default",'[n] ./*[1]; [t] "sub"; [n] ./*[2] (pitch:-0.35);[p] (pause:300); [t] "square" (pitch:0.35); [p] (pause:400)',"self::mathml:msubsup","./*[3][text()=2]");(0,sre.MathmlStoreRules.defineRuleAlias_)("square-sub","self::mathml:msubsup","./mathml:mrow=./*[3]","count(./*[3]/*)=1","./*[3]/*[1][text()=2]");
+(0,sre.MathmlStoreRules.defineRule_)("cube-sub","default.default",'[n] ./*[1]; [t] "sub"; [n] ./*[2] (pitch:-0.35);[p] (pause:300); [t] "cube" (pitch:0.35); [p] (pause:400)',"self::mathml:msubsup","./*[3][text()=3]");(0,sre.MathmlStoreRules.defineRuleAlias_)("cube-sub","self::mathml:msubsup","./mathml:mrow=./*[3]","count(./*[3]/*)=1","./*[3]/*[1][text()=3]");(0,sre.MathmlStoreRules.defineRule_)("mj-square","default.default",'[n] ./*[1]/*[1]/*[1]; [t] "square" (pitch:0.35); [p] (pause:300)','self::span[@class="msup"]',
+"./*[1]/*[2]/*[1][text()=2]");(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-square",'self::span[@class="msup"]','./*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',"count(./*[1]/*[2]/*[1]/*)=1","./*[1]/*[2]/*[1]/*[1][text()=2]");(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-square",'self::span[@class="msubsup"]',"CQFmathmlmsup","./*[1]/*[2]/*[1][text()=2]");(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-square",'self::span[@class="msubsup"]',"CQFmathmlmsup",'./*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',
+"count(./*[1]/*[2]/*[1]/*)=1","./*[1]/*[2]/*[1]/*[1][text()=2]");(0,sre.MathmlStoreRules.defineRule_)("mj-cube","default.default",'[n] ./*[1]/*[1]/*[1]; [t] "cube" (pitch:0.35); [p] (pause:300)','self::span[@class="msup"]',"./*[1]/*[2]/*[1][text()=3]");(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-cube",'self::span[@class="msup"]','./*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',"count(./*[1]/*[2]/*[1]/*)=1","./*[1]/*[2]/*[1]/*[1][text()=3]");(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-cube",
+'self::span[@class="msubsup"]',"CQFmathmlmsup","./*[1]/*[2]/*[1][text()=3]");(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-cube",'self::span[@class="msubsup"]',"CQFmathmlmsup",'./*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',"count(./*[1]/*[2]/*[1]/*)=1","./*[1]/*[2]/*[1]/*[1][text()=3]");(0,sre.MathmlStoreRules.defineRule_)("mj-square-sub","default.default",'[n] ./*[1]/*[1]/*[1]; [t] "sub"; [n] ./*[1]/*[3]/*[1] (pitch:-0.35); [p] (pause:300); [t] "square" (pitch:0.35); [p] (pause:400)','self::span[@class="msubsup"]',
+"./*[1]/*[2]/*[1][text()=2]");(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-square-sub",'self::span[@class="msubsup"]','./*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',"count(./*[1]/*[2]/*[1]/*)=1","./*[1]/*[2]/*[1]/*[1][text()=2]");(0,sre.MathmlStoreRules.defineRule_)("mj-cube-sub","default.default",'[n] ./*[1]/*[1]/*[1]; [t] "sub"; [n] ./*[1]/*[3]/*[1] (pitch:-0.35); [p] (pause:300); [t] "cube" (pitch:0.35); [p] (pause:400)','self::span[@class="msubsup"]',"./*[1]/*[2]/*[1][text()=3]");(0,sre.MathmlStoreRules.defineRuleAlias_)("mj-cube-sub",
+'self::span[@class="msubsup"]','./*[1]/*[2]/*[1]=./*[1]/*[2]/span[@class="mrow"]',"count(./*[1]/*[2]/*[1]/*)=1","./*[1]/*[2]/*[1]/*[1][text()=3]")};sre.MathmlStoreRules.getInstance().initializer=[sre.MathmlStoreRules.initCustomFunctions_,sre.MathmlStoreRules.initDefaultRules_,sre.MathmlStoreRules.initMathjaxRules_,sre.MathmlStoreRules.initAliases_,sre.MathmlStoreRules.initSpecializationRules_];sre.MathspeakRules=function(){sre.MathStore.call(this)};goog.inherits(sre.MathspeakRules,sre.MathStore);goog.addSingletonGetter(sre.MathspeakRules);sre.MathspeakRules.mathStore=sre.MathspeakRules.getInstance();sre.MathspeakRules.defineRule_=goog.bind(sre.MathspeakRules.mathStore.defineRule,sre.MathspeakRules.mathStore);sre.MathspeakRules.defineRuleAlias_=goog.bind(sre.MathspeakRules.mathStore.defineRulesAlias,sre.MathspeakRules.mathStore);
+sre.MathspeakRules.defineSpecialisedRule_=goog.bind(sre.MathspeakRules.mathStore.defineSpecialisedRule,sre.MathspeakRules.mathStore);sre.MathspeakRules.addContextFunction_=goog.bind(sre.MathspeakRules.mathStore.contextFunctions.add,sre.MathspeakRules.mathStore.contextFunctions);sre.MathspeakRules.addCustomQuery_=goog.bind(sre.MathspeakRules.mathStore.customQueries.add,sre.MathspeakRules.mathStore.customQueries);
+sre.MathspeakRules.addCustomString_=goog.bind(sre.MathspeakRules.mathStore.customStrings.add,sre.MathspeakRules.mathStore.customStrings);
+sre.MathspeakRules.initCustomFunctions_=function(){(0,sre.MathspeakRules.addCustomQuery_)("CQFspaceoutNumber",sre.MathspeakUtil.spaceoutNumber);(0,sre.MathspeakRules.addCustomQuery_)("CQFspaceoutIdentifier",sre.MathspeakUtil.spaceoutIdentifier);(0,sre.MathspeakRules.addCustomString_)("CSFspaceoutText",sre.MathspeakUtil.spaceoutText);(0,sre.MathspeakRules.addCustomString_)("CSFopenFracVerbose",sre.MathspeakUtil.openingFractionVerbose);(0,sre.MathspeakRules.addCustomString_)("CSFcloseFracVerbose",sre.MathspeakUtil.closingFractionVerbose);
+(0,sre.MathspeakRules.addCustomString_)("CSFoverFracVerbose",sre.MathspeakUtil.overFractionVerbose);(0,sre.MathspeakRules.addCustomString_)("CSFopenFracBrief",sre.MathspeakUtil.openingFractionBrief);(0,sre.MathspeakRules.addCustomString_)("CSFcloseFracBrief",sre.MathspeakUtil.closingFractionBrief);(0,sre.MathspeakRules.addCustomString_)("CSFopenFracSbrief",sre.MathspeakUtil.openingFractionSbrief);(0,sre.MathspeakRules.addCustomString_)("CSFcloseFracSbrief",sre.MathspeakUtil.closingFractionSbrief);
+(0,sre.MathspeakRules.addCustomString_)("CSFoverFracSbrief",sre.MathspeakUtil.overFractionSbrief);(0,sre.MathspeakRules.addCustomString_)("CSFvulgarFraction",sre.MathspeakUtil.vulgarFraction);(0,sre.MathspeakRules.addCustomQuery_)("CQFvulgarFractionSmall",sre.MathspeakUtil.isSmallVulgarFraction);(0,sre.MathspeakRules.addCustomString_)("CSFopenRadicalVerbose",sre.MathspeakUtil.openingRadicalVerbose);(0,sre.MathspeakRules.addCustomString_)("CSFcloseRadicalVerbose",sre.MathspeakUtil.closingRadicalVerbose);
+(0,sre.MathspeakRules.addCustomString_)("CSFindexRadicalVerbose",sre.MathspeakUtil.indexRadicalVerbose);(0,sre.MathspeakRules.addCustomString_)("CSFopenRadicalBrief",sre.MathspeakUtil.openingRadicalBrief);(0,sre.MathspeakRules.addCustomString_)("CSFcloseRadicalBrief",sre.MathspeakUtil.closingRadicalBrief);(0,sre.MathspeakRules.addCustomString_)("CSFindexRadicalBrief",sre.MathspeakUtil.indexRadicalBrief);(0,sre.MathspeakRules.addCustomString_)("CSFopenRadicalSbrief",sre.MathspeakUtil.openingRadicalSbrief);
+(0,sre.MathspeakRules.addCustomString_)("CSFindexRadicalSbrief",sre.MathspeakUtil.indexRadicalSbrief);(0,sre.MathspeakRules.addCustomString_)("CSFsuperscriptVerbose",sre.MathspeakUtil.superscriptVerbose);(0,sre.MathspeakRules.addCustomString_)("CSFsuperscriptBrief",sre.MathspeakUtil.superscriptBrief);(0,sre.MathspeakRules.addCustomString_)("CSFsubscriptVerbose",sre.MathspeakUtil.subscriptVerbose);(0,sre.MathspeakRules.addCustomString_)("CSFsubscriptBrief",sre.MathspeakUtil.subscriptBrief);(0,sre.MathspeakRules.addCustomString_)("CSFbaselineVerbose",
+sre.MathspeakUtil.baselineVerbose);(0,sre.MathspeakRules.addCustomString_)("CSFbaselineBrief",sre.MathspeakUtil.baselineBrief);(0,sre.MathspeakRules.addCustomString_)("CSFunderscript",sre.MathspeakUtil.nestedUnderscore);(0,sre.MathspeakRules.addCustomString_)("CSFoverscript",sre.MathspeakUtil.nestedOverscore);(0,sre.MathspeakRules.addCustomQuery_)("CQFhideFont",sre.MathmlStoreUtil.hideFont);(0,sre.MathspeakRules.addCustomString_)("CSFshowFont",sre.MathmlStoreUtil.showFont);(0,sre.MathspeakRules.addContextFunction_)("CTXFordinalCounter",
+sre.MathspeakUtil.ordinalCounter);(0,sre.MathspeakRules.addContextFunction_)("CTXFcontentIterator",sre.MathmlStoreUtil.contentIterator);(0,sre.MathspeakRules.addCustomQuery_)("CQFdetIsSimple",sre.MathspeakUtil.determinantIsSimple);(0,sre.MathspeakRules.addCustomString_)("CSFdetMarkSimple",sre.MathspeakUtil.determinantMarkSimple);(0,sre.MathspeakRules.addCustomString_)("CSFdetUnMarkSimple",sre.MathspeakUtil.determinantUnMarkSimple)};
+sre.MathspeakRules.initMathspeakRules_=function(){(0,sre.MathspeakRules.defineRule_)("stree","mathspeak.default","[n] ./*[1]","self::stree");(0,sre.MathspeakRules.defineRule_)("unknown","mathspeak.default","[n] text()","self::unknown");(0,sre.MathspeakRules.defineRule_)("protected","mathspeak.default","[t] text()","self::*",'@role="protected"');(0,sre.MathspeakRules.defineRule_)("omit-empty","mathspeak.default","","self::empty");(0,sre.MathspeakRules.defineRule_)("font","mathspeak.default","[t] @font; [n] CQFhideFont; [t] CSFshowFont",
+"self::*","@font",'@font!="normal"');(0,sre.MathspeakRules.defineRule_)("font-identifier-short","mathspeak.default","[t] @font; [n] CQFhideFont; [t] CSFshowFont","self::identifier","string-length(text())=1","@font",'@font="normal"','""=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9", "")',
+'@role!="unit"');(0,sre.MathspeakRules.defineRule_)("font-identifier","mathspeak.default","[t] @font; [n] CQFhideFont; [t] CSFshowFont","self::identifier","string-length(text())=1","@font",'@font="normal"','@role!="unit"');(0,sre.MathspeakRules.defineRule_)("omit-font","mathspeak.default","[n] CQFhideFont; [t] CSFshowFont","self::identifier","string-length(text())=1","@font",'@font="italic"');(0,sre.MathspeakRules.defineRule_)("german-font","mathspeak.default",'[t] "German"; [n] CQFhideFont; [t] CSFshowFont',
+"self::*","@font",'@font="fraktur"');(0,sre.MathspeakRules.defineRule_)("german-font","mathspeak.default",'[t] "bold German"; [n] CQFhideFont; [t] CSFshowFont',"self::*","@font",'@font="bold-fraktur"');(0,sre.MathspeakRules.defineRule_)("number","mathspeak.default","[n] text()","self::number");(0,sre.MathspeakRules.defineRule_)("mixed-number","mathspeak.default",'[n] children/*[1]; [t] "and"; [n] children/*[2]; ',"self::number",'@role="mixed"');(0,sre.MathspeakRules.defineRule_)("number-with-chars",
+"mathspeak.default",'[t] "Number"; [m] CQFspaceoutNumber',"self::number",'"" != translate(text(), "0123456789.,", "")','text() != translate(text(), "0123456789.,", "")');(0,sre.MathspeakRules.defineSpecialisedRule_)("number-with-chars","mathspeak.default","mathspeak.brief",'[t] "Num"; [m] CQFspaceoutNumber');(0,sre.MathspeakRules.defineSpecialisedRule_)("number-with-chars","mathspeak.brief","mathspeak.sbrief");(0,sre.MathspeakRules.defineRule_)("number-as-upper-word","mathspeak.default",'[t] "UpperWord"; [t] CSFspaceoutText',
+"self::number","string-length(text())>1",'text()=translate(text(), "abcdefghijklmnopqrstuvwxyz\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9", "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9")','""=translate(text(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ\u0391\u0392\u0393\u0394\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e\u039f\u03a0\u03a1\u03a3\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03a9","")');
+(0,sre.MathspeakRules.defineRule_)("number-baseline","mathspeak.default",'[t] "Baseline"; [n] text()',"self::number","not(@hiddenfont)","preceding-sibling::identifier",'preceding-sibling::*[1][@role="latinletter" or @role="greekletter" or @role="otherletter"]','parent::*/parent::infixop[@role="implicit"]');(0,sre.MathspeakRules.defineSpecialisedRule_)("number-baseline","mathspeak.default","mathspeak.brief",'[t] "Base"; [n] text()');(0,sre.MathspeakRules.defineSpecialisedRule_)("number-baseline","mathspeak.brief",
+"mathspeak.sbrief");(0,sre.MathspeakRules.defineRule_)("number-baseline-font","mathspeak.default",'[t] "Baseline"; [t] @font; [n] CQFhideFont; [t] CSFshowFont',"self::number","@font",'@font!="normal"',"preceding-sibling::identifier",'preceding-sibling::*[@role="latinletter" or @role="greekletter" or @role="otherletter"]','parent::*/parent::infixop[@role="implicit"]');(0,sre.MathspeakRules.defineSpecialisedRule_)("number-baseline-font","mathspeak.default","mathspeak.brief",'[t] "Base"; [n] text()');
+(0,sre.MathspeakRules.defineSpecialisedRule_)("number-baseline-font","mathspeak.brief","mathspeak.sbrief");(0,sre.MathspeakRules.defineRule_)("identifier","mathspeak.default","[m] CQFspaceoutIdentifier","self::identifier","string-length(text())>1",'@role!="unit"','@role!="protected"','not(@font) or @font="normal" or @hiddenfont');(0,sre.MathspeakRules.defineRule_)("identifier","mathspeak.default","[n] text()","self::identifier",'@role="protected"');(0,sre.MathspeakRules.defineRule_)("negative","mathspeak.default",
+'[t] "negative"; [n] children/*[1]',"self::prefixop",'@role="negative"',"children/identifier");(0,sre.MathspeakRules.defineRuleAlias_)("negative","self::prefixop",'@role="negative"',"children/number");(0,sre.MathspeakRules.defineRuleAlias_)("negative","self::prefixop",'@role="negative"','children/fraction[@role="vulgar"]');(0,sre.MathspeakRules.defineRule_)("negative","mathspeak.default",'[t] "minus"; [n] children/*[1]',"self::prefixop",'@role="negative"');(0,sre.MathspeakRules.defineRule_)("prefix",
+"mathspeak.default","[n] text(); [n] children/*[1]","self::prefixop");(0,sre.MathspeakRules.defineRule_)("postfix","mathspeak.default","[n] children/*[1]; [n] text()","self::postfixop");(0,sre.MathspeakRules.defineRule_)("binary-operation","mathspeak.default","[m] children/* (sepFunc:CTXFcontentIterator);","self::infixop");(0,sre.MathspeakRules.defineRule_)("implicit","mathspeak.default","[m] children/*","self::infixop",'@role="implicit"');(0,sre.MathspeakRules.defineRuleAlias_)("implicit","self::infixop",
+'@role="leftsuper" or @role="leftsub" or @role="rightsuper" or @role="rightsub"');(0,sre.MathspeakRules.defineRule_)("subtraction","mathspeak.default",'[m] children/* (separator:"minus");',"self::infixop",'@role="subtraction"');(0,sre.MathspeakRules.defineRule_)("function-unknown","mathspeak.default","[n] children/*[1]; [n] children/*[2]","self::appl");(0,sre.MathspeakRules.defineRule_)("function-prefix","mathspeak.default","[n] children/*[1]; [n] children/*[2]","self::appl",'children/*[1][@role="prefix function"]');
+(0,sre.MathspeakRules.defineRule_)("fences-open-close","mathspeak.default","[n] content/*[1]; [n] children/*[1]; [n] content/*[2]","self::fenced",'@role="leftright"');(0,sre.MathspeakRules.defineRule_)("fences-neutral","mathspeak.default",'[t] "StartAbsoluteValue"; [n] children/*[1]; [t] "EndAbsoluteValue"',"self::fenced",'self::fenced[@role="neutral"]','content/*[1][text()]="|" or content/*[1][text()]="\u2758" or content/*[1][text()]="\uff5c"');(0,sre.MathspeakRules.defineSpecialisedRule_)("fences-neutral",
+"mathspeak.default","mathspeak.sbrief",'[t] "AbsoluteValue"; [n] children/*[1]; [t] "EndAbsoluteValue"');(0,sre.MathspeakRules.defineRule_)("fences-neutral","mathspeak.default","[n] content/*[1]; [n] children/*[1]; [n] content/*[2]","self::fenced",'self::fenced[@role="neutral"]');(0,sre.MathspeakRules.defineRule_)("fences-set","mathspeak.default",'[t] "StartSet"; [n] children/*[1]; [t] "EndSet"','self::fenced[@role="leftright"]','content/*[1][text()]="{"','content/*[2][text()]="}"',"count(children/*)=1",
+'not(name(../..)="appl")');(0,sre.MathspeakRules.defineSpecialisedRule_)("fences-set","mathspeak.default","mathspeak.sbrief",'[t] "Set"; [n] children/*[1]; [t] "EndSet"');(0,sre.MathspeakRules.defineRule_)("text","mathspeak.default","[n] text()","self::text");(0,sre.MathspeakRules.defineRule_)("factorial","mathspeak.default",'[t] "factorial"',"self::punctuation",'text()="!"','name(preceding-sibling::*[1])!="text"');(0,sre.MathspeakRules.defineRule_)("minus","mathspeak.default",'[t] "minus"',"self::operator",
+'text()="-"');(0,sre.MathspeakRules.defineRule_)("single-prime","mathspeak.default",'[t] "prime"','self::punctuated[@role="prime"]',"count(children/*)=1");(0,sre.MathspeakRules.defineRule_)("double-prime","mathspeak.default",'[t] "double-prime"','self::punctuated[@role="prime"]',"count(children/*)=2");(0,sre.MathspeakRules.defineRule_)("triple-prime","mathspeak.default",'[t] "triple-prime"','self::punctuated[@role="prime"]',"count(children/*)=3");(0,sre.MathspeakRules.defineRule_)("quadruple-prime",
+"mathspeak.default",'[t] "quadruple-prime"','self::punctuated[@role="prime"]',"count(children/*)=4");(0,sre.MathspeakRules.defineRule_)("counted-prime","mathspeak.default",'[t] count(children/*); [t] "prime"','self::punctuated[@role="prime"]');(0,sre.MathspeakRules.defineRule_)("fraction","mathspeak.default","[t] CSFopenFracVerbose; [n] children/*[1]; [t] CSFoverFracVerbose; [n] children/*[2]; [t] CSFcloseFracVerbose","self::fraction");(0,sre.MathspeakRules.defineRule_)("fraction","mathspeak.brief",
+"[t] CSFopenFracBrief; [n] children/*[1]; [t] CSFoverFracVerbose; [n] children/*[2]; [t] CSFcloseFracBrief","self::fraction");(0,sre.MathspeakRules.defineRule_)("fraction","mathspeak.sbrief","[t] CSFopenFracSbrief; [n] children/*[1]; [t] CSFoverFracSbrief; [n] children/*[2]; [t] CSFcloseFracSbrief","self::fraction");(0,sre.MathspeakRules.defineRule_)("vulgar-fraction","mathspeak.default","[t] CSFvulgarFraction","self::fraction",'@role="vulgar"',"CQFvulgarFractionSmall");(0,sre.MathspeakRules.defineSpecialisedRule_)("vulgar-fraction",
+"mathspeak.default","mathspeak.brief");(0,sre.MathspeakRules.defineSpecialisedRule_)("vulgar-fraction","mathspeak.default","mathspeak.sbrief");(0,sre.MathspeakRules.defineRule_)("continued-fraction-outer","mathspeak.default",'[t] "ContinuedFraction"; [n] children/*[1];[t] "Over"; [n] children/*[2]',"self::fraction","not(ancestor::fraction)",'children/*[2]/descendant-or-self::*[@role="ellipsis" and not(following-sibling::*)]');(0,sre.MathspeakRules.defineSpecialisedRule_)("continued-fraction-outer",
+"mathspeak.default","mathspeak.brief",'[t] "ContinuedFrac"; [n] children/*[1];[t] "Over"; [n] children/*[2]');(0,sre.MathspeakRules.defineSpecialisedRule_)("continued-fraction-outer","mathspeak.brief","mathspeak.sbrief");(0,sre.MathspeakRules.defineRule_)("continued-fraction-inner","mathspeak.default",'[t] "StartFraction"; [n] children/*[1];[t] "Over"; [n] children/*[2]',"self::fraction","ancestor::fraction",'children/*[2]/descendant-or-self::*[@role="ellipsis" and not(following-sibling::*)]');(0,sre.MathspeakRules.defineSpecialisedRule_)("continued-fraction-inner",
+"mathspeak.default","mathspeak.brief",'[t] "StartFrac"; [n] children/*[1];[t] "Over"; [n] children/*[2]');(0,sre.MathspeakRules.defineSpecialisedRule_)("continued-fraction-inner","mathspeak.brief","mathspeak.sbrief",'[t] "Frac"; [n] children/*[1];[t] "Over"; [n] children/*[2]');(0,sre.MathspeakRules.defineRule_)("sqrt","mathspeak.default","[t] CSFopenRadicalVerbose; [n] children/*[1]; [t] CSFcloseRadicalVerbose","self::sqrt");(0,sre.MathspeakRules.defineRule_)("sqrt","mathspeak.brief","[t] CSFopenRadicalBrief; [n] children/*[1]; [t] CSFcloseRadicalBrief",
+"self::sqrt");(0,sre.MathspeakRules.defineRule_)("sqrt","mathspeak.sbrief","[t] CSFopenRadicalSbrief; [n] children/*[1]; [t] CSFcloseRadicalBrief","self::sqrt");(0,sre.MathspeakRules.defineRule_)("root","mathspeak.default","[t] CSFindexRadicalVerbose; [n] children/*[1];[t] CSFopenRadicalVerbose; [n] children/*[2]; [t] CSFcloseRadicalVerbose","self::root");(0,sre.MathspeakRules.defineRule_)("root","mathspeak.brief","[t] CSFindexRadicalBrief; [n] children/*[1];[t] CSFopenRadicalBrief; [n] children/*[2]; [t] CSFcloseRadicalBrief",
+"self::root");(0,sre.MathspeakRules.defineRule_)("root","mathspeak.sbrief","[t] CSFindexRadicalSbrief; [n] children/*[1];[t] CSFopenRadicalSbrief; [n] children/*[2]; [t] CSFcloseRadicalBrief","self::root");(0,sre.MathspeakRules.defineRule_)("limboth","mathspeak.default","[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];[t] CSFoverscript; [n] children/*[3]","self::limboth",'name(../..)="underscore" or name(../..)="overscore"','following-sibling::*[@role!="underaccent" and @role!="overaccent"]');
+(0,sre.MathspeakRules.defineRule_)("limlower","mathspeak.default","[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];","self::limlower",'name(../..)="underscore" or name(../..)="overscore"','following-sibling::*[@role!="underaccent" and @role!="overaccent"]');(0,sre.MathspeakRules.defineRule_)("limupper","mathspeak.default","[n] children/*[1]; [t] CSFoverscript; [n] children/*[2];","self::limupper",'name(../..)="underscore" or name(../..)="overscore"','following-sibling::*[@role!="underaccent" and @role!="overaccent"]');
+(0,sre.MathspeakRules.defineRuleAlias_)("limlower","self::underscore",'@role="limit function"','name(../..)="underscore" or name(../..)="overscore"','following-sibling::*[@role!="underaccent" and @role!="overaccent"]');(0,sre.MathspeakRules.defineRuleAlias_)("limlower","self::underscore",'children/*[2][@role!="underaccent"]','name(../..)="underscore" or name(../..)="overscore"','following-sibling::*[@role!="underaccent" and @role!="overaccent"]');(0,sre.MathspeakRules.defineRuleAlias_)("limupper",
+"self::overscore",'children/*[2][@role!="overaccent"]','name(../..)="underscore" or name(../..)="overscore"','following-sibling::*[@role!="underaccent" and @role!="overaccent"]');(0,sre.MathspeakRules.defineRule_)("limboth-end","mathspeak.default",'[n] children/*[1]; [t] CSFunderscript; [n] children/*[2];[t] CSFoverscript; [n] children/*[3]; [t] "Endscripts"',"self::limboth");(0,sre.MathspeakRules.defineRule_)("limlower-end","mathspeak.default",'[n] children/*[1]; [t] CSFunderscript; [n] children/*[2]; [t] "Endscripts"',
+"self::limlower");(0,sre.MathspeakRules.defineRule_)("limupper-end","mathspeak.default",'[n] children/*[1]; [t] CSFoverscript; [n] children/*[2]; [t] "Endscripts"',"self::limupper");(0,sre.MathspeakRules.defineRuleAlias_)("limlower-end","self::underscore",'@role="limit function"');(0,sre.MathspeakRules.defineRuleAlias_)("limlower-end","self::underscore");(0,sre.MathspeakRules.defineRuleAlias_)("limupper-end","self::overscore");(0,sre.MathspeakRules.defineRule_)("integral","mathspeak.default","[n] children/*[1]; [n] children/*[2]; [n] children/*[3];",
+"self::integral");(0,sre.MathspeakRules.defineRule_)("integral","mathspeak.default",'[n] children/*[1]; [t] "Subscript"; [n] children/*[2];[t] "Superscript"; [n] children/*[3]; [t] "Baseline";',"self::limboth",'@role="integral"');(0,sre.MathspeakRules.defineSpecialisedRule_)("integral","mathspeak.default","mathspeak.brief",'[n] children/*[1]; [t] "Sub"; [n] children/*[2];[t] "Sup"; [n] children/*[3]; [t] "Base&q